ZQuest Classic Coverage Report


Directory: src/
File: src/zc/maps.cpp
Date: 2025-06-30 08:47:23
Exec Total Coverage
Lines: 3998 5028 79.5%
Functions: 275 322 85.4%
Branches: 3094 5073 61.0%

Line Branch Exec Source
1 #include "base/combo.h"
2 #include "base/handles.h"
3 #include "base/util.h"
4 #include "base/zdefs.h"
5 #include "base/general.h"
6 #include <cstring>
7 #include <assert.h>
8 #include <math.h>
9 #include <vector>
10 #include <deque>
11 #include <string>
12 #include <set>
13 #include <array>
14 #include <sstream>
15 using std::set;
16
17 #include "base/qrs.h"
18 #include "base/dmap.h"
19 #include "base/mapscr.h"
20 #include "base/misctypes.h"
21 #include "base/initdata.h"
22 #include "zc/maps.h"
23 #include "zc/zelda.h"
24 #include "zc/zc_ffc.h"
25 #include "tiles.h"
26 #include "sprite.h"
27 #include "gui/jwin.h"
28 #include "base/zsys.h"
29 #include "subscr.h"
30 #include "zc/zc_subscr.h"
31 #include "zc/hero.h"
32 #include "zc/guys.h"
33 #include "zc/ffscript.h"
34 #include "drawing.h"
35 #include "zc/combos.h"
36 #include "zc/replay.h"
37 #include "slopes.h"
38 #include "particles.h"
39 #include <fmt/format.h>
40 #include "zc/render.h"
41 #include "iter.h"
42 #include <ranges>
43
44 // All the temporary screens (and their layers) for the currently loaded map.
45 static mapscr* temporary_screens[136*7];
46 // Set by load_region.
47 static bool screen_in_current_region[136];
48 404 static rpos_handle_t current_region_rpos_handles[136*7];
49 static bool current_region_rpos_handles_dirty;
50 static int current_region_screen_count;
51 static std::pair<const rpos_handle_t*, int> current_region_rpos_handles_scr[136];
52
53 viewport_t viewport;
54 static int viewport_sprite_uid;
55 ViewportMode viewport_mode;
56 int world_w, world_h;
57 int region_scr_dx, region_scr_dy;
58 int region_scr_count;
59 rpos_t region_max_rpos;
60 int region_num_rpos;
61 region_t cur_region, scrolling_region;
62
63 404 maze_state_t maze_state;
64 int scrolling_maze_last_solved_screen;
65
66 568 void maps_init_game_vars()
67 {
68 568 viewport = {};
69 568 viewport_mode = ViewportMode::CenterAndBound;
70 568 viewport_sprite_uid = 1;
71 568 currscr_for_passive_subscr = -1;
72 568 }
73
74 static region_ids_t current_region_ids;
75
76 14604306 static bool is_a_region(int map, int scr)
77 {
78 14604306 return get_region_id(map, scr) != 0;
79 }
80
81 2232 static bool is_same_region_id(int region_origin_scr, int map, int scr)
82 {
83
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 1460 times.
2232 if (!is_a_region(map, scr)) return false;
84 1460 int region_id = get_region_id(map, region_origin_scr);
85
1/2
✓ Branch 0 taken 1460 times.
✗ Branch 1 not taken.
1460 return region_id && region_id == get_region_id(map, scr);
86 2232 }
87
88 136565347 bool is_in_current_region(int map, int screen)
89 {
90
5/6
✓ Branch 0 taken 136563774 times.
✓ Branch 1 taken 1573 times.
✓ Branch 2 taken 136563774 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12213 times.
✓ Branch 5 taken 136551561 times.
136565347 return map == cur_map && screen >= 0 && screen < 128 && screen_in_current_region[screen];
91 }
92
93 69602902 bool is_in_current_region(int screen)
94 {
95
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 69602901 times.
69602902 return screen < 128 && screen_in_current_region[screen];
96 }
97
98 28868665 bool is_in_current_region(mapscr* scr)
99 {
100
4/4
✓ Branch 0 taken 28853655 times.
✓ Branch 1 taken 15010 times.
✓ Branch 2 taken 461910 times.
✓ Branch 3 taken 28391745 times.
28868665 return scr->map == cur_map && scr->screen < 128 && screen_in_current_region[scr->screen];
101 }
102
103 bool is_in_scrolling_region(int screen)
104 {
105 if (!screenscrolling) return false;
106
107 int x = screen % 16;
108 int y = screen / 16;
109 return
110 scrolling_region.origin_screen_x >= x && scrolling_region.origin_screen_x < x + scrolling_region.screen_width &&
111 scrolling_region.origin_screen_y >= y && scrolling_region.origin_screen_y < y + scrolling_region.screen_height;
112 }
113
114 9017095586 bool is_in_scrolling_region()
115 {
116 9017095586 return cur_region.screen_count > 1;
117 }
118
119 76764541 bool is_extended_height_mode()
120 {
121
2/2
✓ Branch 0 taken 76514407 times.
✓ Branch 1 taken 250134 times.
76764541 return cur_region.screen_height > 1 && (DMaps[cur_dmap].flags & dmfEXTENDEDVIEWPORT);
122 }
123
124 // Returns 0 if this is not a region.
125 15646322 int get_region_id(int map, int screen)
126 {
127
2/2
✓ Branch 0 taken 401435 times.
✓ Branch 1 taken 15244887 times.
15646322 if (screen >= 128) return 0;
128
2/2
✓ Branch 0 taken 15243787 times.
✓ Branch 1 taken 1100 times.
15244887 if (map == cur_region.map) return current_region_ids[screen];
129
130 1100 return Regions[map].get_region_id(screen);
131 15646322 }
132
133 982758 int get_current_region_id()
134 {
135 982758 return get_region_id(cur_map, cur_screen);
136 }
137
138 64176 void calculate_region(int map, int screen, region_t& region, int& region_scr_dx, int& region_scr_dy)
139 {
140 64176 region.map = map;
141
142
3/4
✓ Branch 0 taken 274 times.
✓ Branch 1 taken 63902 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 274 times.
64176 if (!(is_a_region(map, screen)) || screen >= 0x80)
143 {
144 63902 region.region_id = 0;
145 63902 region.origin_screen = screen;
146 63902 region.origin_screen_x = screen % 16;
147 63902 region.origin_screen_y = screen / 16;
148 63902 region.screen_width = 1;
149 63902 region.screen_height = 1;
150 63902 region.screen_count = 1;
151 63902 region.width = 256;
152 63902 region.height = 176;
153 63902 region_scr_dx = 0;
154 63902 region_scr_dy = 0;
155 63902 return;
156 }
157
158 274 int input_scr_x = screen % 16;
159 274 int input_scr_y = screen / 16;
160
161 // For the given screen, find the top-left corner of its region.
162 274 int origin_scr_x = input_scr_x;
163 274 int origin_scr_y = input_scr_y;
164 274 int origin_scr = screen;
165
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 372 times.
434 while (origin_scr_x > 0)
166 {
167
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 160 times.
372 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x - 1, origin_scr_y))) break;
168 160 origin_scr_x--;
169 }
170
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 414 times.
508 while (origin_scr_y > 0)
171 {
172
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 234 times.
414 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, origin_scr_y - 1))) break;
173 234 origin_scr_y--;
174 }
175 274 origin_scr = map_scr_xy_to_index(origin_scr_x, origin_scr_y);
176
177 // Now find the bottom-right corner.
178 274 int region_scr_right = origin_scr_x;
179
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 614 times.
642 while (region_scr_right < 15)
180 {
181
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 368 times.
614 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(region_scr_right + 1, origin_scr_y))) break;
182 368 region_scr_right++;
183 }
184 274 int region_scr_bottom = origin_scr_y;
185
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 832 times.
856 while (region_scr_bottom < 7)
186 {
187
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 582 times.
832 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, region_scr_bottom + 1))) break;
188 582 region_scr_bottom++;
189 }
190
191 274 region.region_id = get_region_id(map, origin_scr);
192 274 region.origin_screen = origin_scr;
193 274 region.origin_screen_x = origin_scr_x;
194 274 region.origin_screen_y = origin_scr_y;
195 274 region.screen_width = region_scr_right - origin_scr_x + 1;
196 274 region.screen_height = region_scr_bottom - origin_scr_y + 1;
197 274 region.screen_count = region.screen_width * region.screen_height;
198 274 region.width = 256 * region.screen_width;
199 274 region.height = 176 * region.screen_height;
200 274 region_scr_dx = input_scr_x - origin_scr_x;
201 274 region_scr_dy = input_scr_y - origin_scr_y;
202
203 DCHECK_RANGE_INCLUSIVE(region.screen_width, 0, 16);
204 DCHECK_RANGE_INCLUSIVE(region.screen_height, 0, 8);
205 64176 }
206
207 35830 void load_region(int dmap, int screen)
208 {
209 35830 clear_temporary_screens();
210
211 35830 int map = DMaps[dmap].map;
212 35830 current_region_ids = Regions[map].get_all_region_ids();
213
214 35830 calculate_region(map, screen, cur_region, region_scr_dx, region_scr_dy);
215 35830 cur_screen = cur_region.origin_screen;
216 35830 world_w = cur_region.width;
217 35830 world_h = cur_region.height;
218 35830 region_scr_count = cur_region.screen_count;
219 35830 region_max_rpos = (rpos_t)(cur_region.screen_count*176 - 1);
220 35830 region_num_rpos = cur_region.screen_count*176;
221 35830 scrolling_maze_last_solved_screen = 0;
222
223 35830 memset(screen_in_current_region, false, sizeof(screen_in_current_region));
224
2/2
✓ Branch 0 taken 36064 times.
✓ Branch 1 taken 35830 times.
71894 for (int x = 0; x < cur_region.screen_width; x++)
225 {
226
2/2
✓ Branch 0 taken 37074 times.
✓ Branch 1 taken 36064 times.
73138 for (int y = 0; y < cur_region.screen_height; y++)
227 {
228 37074 int screen = cur_screen + x + y*16;
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37074 times.
37074 if (screen < 136)
230 {
231 37074 screen_in_current_region[screen] = true;
232 37074 }
233 37074 }
234 36064 }
235
236 35830 mark_current_region_handles_dirty();
237 35830 }
238
239 35830 static void prepare_current_region_handles()
240 {
241 35830 current_region_rpos_handles_dirty = false;
242 35830 current_region_screen_count = 0;
243
2/2
✓ Branch 0 taken 36178 times.
✓ Branch 1 taken 35830 times.
72008 for (int y = 0; y < cur_region.screen_height; y++)
244 {
245
2/2
✓ Branch 0 taken 37074 times.
✓ Branch 1 taken 36178 times.
73252 for (int x = 0; x < cur_region.screen_width; x++)
246 {
247 37074 int screen = cur_screen + x + y*16;
248 37074 int index_start = current_region_screen_count;
249
2/2
✓ Branch 0 taken 37074 times.
✓ Branch 1 taken 259518 times.
296592 for (int layer = 0; layer <= 6; layer++)
250 {
251 259518 mapscr* scr = get_scr_layer(screen, layer);
252
2/2
✓ Branch 0 taken 84481 times.
✓ Branch 1 taken 175037 times.
259518 if (!scr->is_valid())
253 {
254
1/2
✓ Branch 0 taken 175037 times.
✗ Branch 1 not taken.
175037 if (layer == 0) break;
255 175037 continue;
256 }
257
258 84481 rpos_t base_rpos = POS_TO_RPOS(0, get_region_relative_dx(screen), get_region_relative_dy(screen));
259 84481 current_region_rpos_handles[current_region_screen_count] = {scr, screen, layer, base_rpos, 0};
260 84481 current_region_screen_count += 1;
261 84481 }
262
263 37074 int num_handles_for_scr = current_region_screen_count - index_start;
264 37074 current_region_rpos_handles_scr[screen] = {&current_region_rpos_handles[index_start], num_handles_for_scr};
265 37074 }
266 36178 }
267 35830 }
268
269 1780123826 std::tuple<const rpos_handle_t*, int> get_current_region_handles()
270 {
271 DCHECK(!current_region_rpos_handles_dirty);
272 1780123826 return {current_region_rpos_handles, current_region_screen_count};
273 }
274
275 11029928 std::tuple<const rpos_handle_t*, int> get_current_region_handles(mapscr* scr)
276 {
277 DCHECK(!current_region_rpos_handles_dirty);
278
2/4
✓ Branch 0 taken 11029928 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11029928 times.
11029928 if (scr == special_warp_return_scr || current_region_rpos_handles_dirty)
279 return {nullptr, 0};
280
281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11029928 times.
11029928 if (cur_screen >= 0x80)
282 {
283 DCHECK(scr == origin_scr);
284 return {nullptr, 0};
285 }
286
287 DCHECK(is_in_current_region(scr));
288 11029928 return current_region_rpos_handles_scr[scr->screen];
289 11029928 }
290
291 35830 void mark_current_region_handles_dirty()
292 {
293 35830 current_region_rpos_handles_dirty = true;
294 35830 }
295
296 36960 void clear_temporary_screens()
297 {
298
2/2
✓ Branch 0 taken 35185920 times.
✓ Branch 1 taken 36960 times.
35222880 for (int i = 0; i < 136*7; i++)
299 {
300
2/2
✓ Branch 0 taken 35131334 times.
✓ Branch 1 taken 54586 times.
35185920 if (temporary_screens[i])
301 {
302 54586 free(temporary_screens[i]);
303 54586 temporary_screens[i] = NULL;
304 54586 }
305 35185920 }
306
307 36960 origin_scr = nullptr;
308 36960 hero_scr = nullptr;
309 36960 }
310
311 27941 std::vector<mapscr*> take_temporary_scrs()
312 {
313
1/2
✓ Branch 0 taken 27941 times.
✗ Branch 1 not taken.
27941 std::vector<mapscr*> screens(temporary_screens, temporary_screens + 136*7);
314
2/2
✓ Branch 0 taken 27941 times.
✓ Branch 1 taken 26599832 times.
26627773 for (int i = 0; i < 136*7; i++)
315 26599832 temporary_screens[i] = nullptr;
316
317 27941 return screens;
318
1/2
✓ Branch 0 taken 27941 times.
✗ Branch 1 not taken.
27941 }
319
320 14538258 void calculate_viewport(viewport_t& viewport, int dmap, int screen, int world_w, int world_h, int x, int y)
321 {
322 // TODO: In future, maybe add x/y centering offsets to zscript (Viewport->TargetXOffset/Viewport->TargetYOffset).
323
324
2/2
✓ Branch 0 taken 14491676 times.
✓ Branch 1 taken 46582 times.
14538258 bool extended_height_mode = (DMaps[dmap].flags & dmfEXTENDEDVIEWPORT) && world_h > 176;
325 14538258 viewport.w = 256;
326 14538258 viewport.h = 176 + (extended_height_mode ? 56 : 0);
327
328
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 14537898 times.
14538258 if (viewport_mode == ViewportMode::Script)
329 360 return;
330
331
2/2
✓ Branch 0 taken 46162 times.
✓ Branch 1 taken 14491736 times.
14537898 if (!is_a_region(DMaps[dmap].map, screen))
332 {
333 14491736 viewport.x = 0;
334 14491736 viewport.y = 0;
335 14491736 }
336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46162 times.
46162 else if (viewport_mode == ViewportMode::CenterAndBound)
337 {
338 // Clamp the viewport to the edges of the region.
339
6/6
✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 37594 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 39374 times.
✓ Branch 4 taken 8568 times.
✓ Branch 5 taken 30806 times.
46162 viewport.x = CLAMP(0, world_w - viewport.w, x - viewport.w/2);
340
6/6
✓ Branch 0 taken 11856 times.
✓ Branch 1 taken 34306 times.
✓ Branch 2 taken 5650 times.
✓ Branch 3 taken 40512 times.
✓ Branch 4 taken 11856 times.
✓ Branch 5 taken 28656 times.
46162 viewport.y = CLAMP(0, world_h - viewport.h, y - viewport.h/2);
341 46162 }
342 else if (viewport_mode == ViewportMode::Center)
343 {
344 viewport.x = x - viewport.w/2;
345 viewport.y = y - viewport.h/2;
346 }
347 14538258 }
348
349 14537747 sprite* get_viewport_sprite()
350 {
351 14537747 sprite* spr = sprite::getByUID(viewport_sprite_uid);
352
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 14537741 times.
14537747 if (!spr)
353 {
354 6 viewport_sprite_uid = 1; // Hero uid.
355 6 spr = &Hero;
356 6 }
357
358 14537747 return spr;
359 }
360
361 6 void set_viewport_sprite(sprite* spr)
362 {
363 6 viewport_sprite_uid = spr->uid;
364 6 }
365
366 14509806 void update_viewport()
367 {
368 14509806 sprite* spr = get_viewport_sprite();
369 14509806 int x = spr->x + spr->txsz*16/2;
370 14509806 int y = spr->y + spr->tysz*16/2;
371 14509806 calculate_viewport(viewport, cur_dmap, cur_screen, world_w, world_h, x, y);
372 14509806 }
373
374 14297650 void update_heroscr()
375 {
376 void playLevelMusic();
377
378 14297650 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
379 14297650 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
380 14297650 int dx = x / 256;
381 14297650 int dy = y / 176;
382 14297650 int new_screen = cur_screen + dx + dy * 16;
383
2/2
✓ Branch 0 taken 14289888 times.
✓ Branch 1 taken 7762 times.
14297650 if (maze_state.active == 1)
384 7762 new_screen = maze_state.scr->screen;
385
7/12
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 14297434 times.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 216 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 216 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 216 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 216 times.
14297650 if (hero_screen != new_screen && dx >= 0 && dy >= 0 && dx < 16 && dy < 8 && is_in_current_region(new_screen))
386 {
387 216 region_scr_dx = dx;
388 216 region_scr_dy = dy;
389 216 hero_screen = new_screen;
390 216 prev_hero_scr = hero_scr;
391 216 hero_scr = get_scr(hero_screen);
392 216 Hero.screen_spawned = hero_screen;
393 216 playLevelMusic();
394 216 }
395
1/2
✓ Branch 0 taken 14297650 times.
✗ Branch 1 not taken.
14297650 if (game->get_regionmapping() == REGION_MAPPING_PHYSICAL)
396 mark_visited(new_screen); // Mark each screen the hero steps foot in as visited
397 14297650 }
398
399 4722 mapscr* determine_hero_screen_from_coords()
400 {
401 4722 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
402 4722 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
403 4722 int dx = x / 256;
404 4722 int dy = y / 176;
405 4722 return get_scr(cur_screen + dx + dy * 16);
406 }
407
408 26911 bool edge_of_region(direction dir)
409 {
410
2/2
✓ Branch 0 taken 26831 times.
✓ Branch 1 taken 80 times.
26911 if (!is_in_scrolling_region()) return true;
411
412 80 int screen_x = hero_screen % 16;
413 80 int screen_y = hero_screen / 16;
414
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if (dir == up) screen_y -= 1;
415
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 10 times.
80 if (dir == down) screen_y += 1;
416
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 30 times.
80 if (dir == left) screen_x -= 1;
417
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 38 times.
80 if (dir == right) screen_x += 1;
418
4/8
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
80 if (screen_x < 0 || screen_x > 16 || screen_y < 0 || screen_y > 8) return true;
419 80 return !is_in_current_region(map_scr_xy_to_index(screen_x, screen_y));
420 26911 }
421
422 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
423 // Coordinates are clamped to the world bounds.
424 211982041 int get_screen_for_world_xy(int x, int y)
425 {
426
2/2
✓ Branch 0 taken 189194949 times.
✓ Branch 1 taken 22787092 times.
211982041 if (!is_in_scrolling_region())
427 189194949 return cur_screen;
428
429 22787092 int dx = std::clamp(x, 0, world_w - 1) / 256;
430 22787092 int dy = std::clamp(y, 0, world_h - 1) / 176;
431 22787092 int origin_screen_x = cur_screen % 16;
432 22787092 int origin_screen_y = cur_screen / 16;
433 22787092 int scr_x = origin_screen_x + dx;
434 22787092 int scr_y = origin_screen_y + dy;
435 22787092 return map_scr_xy_to_index(scr_x, scr_y);
436 211982041 }
437
438 32518504 int get_screen_for_rpos(rpos_t rpos)
439 {
440 32518504 int origin_screen_x = cur_screen % 16;
441 32518504 int origin_screen_y = cur_screen / 16;
442 32518504 int screen = static_cast<int32_t>(rpos) / 176;
443 32518504 int scr_x = origin_screen_x + screen%cur_region.screen_width;
444 32518504 int scr_y = origin_screen_y + screen/cur_region.screen_width;
445 32518504 return map_scr_xy_to_index(scr_x, scr_y);
446 }
447
448 773455034 rpos_handle_t get_rpos_handle(rpos_t rpos, int layer)
449 {
450 DCHECK_LAYER_ZERO_INDEX(layer);
451
2/2
✓ Branch 0 taken 741074490 times.
✓ Branch 1 taken 32380544 times.
773455034 if (!is_in_scrolling_region())
452 741074490 return {get_scr_layer(cur_screen, layer), cur_screen, layer, rpos, RPOS_TO_POS(rpos)};
453 32380544 int screen = get_screen_for_rpos(rpos);
454 32380544 mapscr* scr = get_scr_layer(screen, layer);
455 32380544 return {scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
456 773455034 }
457
458 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
459 // Coordinates are clamped to the world bounds.
460 3498622148 rpos_handle_t get_rpos_handle_for_world_xy(int x, int y, int layer)
461 {
462 3498622148 x = std::clamp(x, 0, world_w - 1);
463 3498622148 y = std::clamp(y, 0, world_h - 1);
464
465 DCHECK_LAYER_ZERO_INDEX(layer);
466
2/2
✓ Branch 0 taken 3470884976 times.
✓ Branch 1 taken 27737172 times.
3498622148 if (!is_in_scrolling_region())
467 {
468 3470884976 int pos = COMBOPOS(x, y);
469 3470884976 return {get_scr_layer(cur_screen, layer), cur_screen, layer, (rpos_t)pos, pos};
470 }
471 27737172 return get_rpos_handle(COMBOPOS_REGION(x, y), layer);
472 3498622148 }
473
474 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
475 44 rpos_handle_t get_rpos_handle_for_screen(int screen, int layer, int pos)
476 {
477 DCHECK_LAYER_ZERO_INDEX(layer);
478 44 return {get_scr_layer(screen, layer), screen, layer, POS_TO_RPOS(pos, screen), pos};
479 }
480
481 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
482 // Use this instead of the other `get_pos_handle_for_screen` if you already have a reference to the screen.
483 62245 rpos_handle_t get_rpos_handle_for_scr(mapscr* scr, int layer, int pos)
484 {
485 DCHECK_LAYER_ZERO_INDEX(layer);
486 62245 return {scr, scr->screen, layer, POS_TO_RPOS(pos, scr->screen), pos};
487 }
488
489 25143384 void change_rpos_handle_layer(rpos_handle_t& rpos_handle, int layer)
490 {
491 DCHECK_LAYER_ZERO_INDEX(layer);
492 25143384 rpos_handle.layer = layer;
493 25143384 rpos_handle.scr = get_scr_layer(rpos_handle.screen, layer);
494 25143384 }
495
496 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
497 // Coordinates are clamped to the world bounds.
498 52808 combined_handle_t get_combined_handle_for_world_xy(int x, int y, int layer)
499 {
500 DCHECK_LAYER_ZERO_INDEX(layer);
501
502 52808 x = std::clamp(x, 0, world_w - 1);
503 52808 y = std::clamp(y, 0, world_h - 1);
504
505 52808 auto maybe_ffc_handle = getFFCAt(x, y);
506
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (maybe_ffc_handle)
507 return maybe_ffc_handle.value();
508
509 52808 auto rpos = COMBOPOS_REGION_B(x, y);
510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (rpos == rpos_t::None)
511 return rpos_handle_t();
512 52808 return get_rpos_handle(rpos, layer);
513 52808 }
514
515 // These functions all return _temporary_ screens. Any modifications made to them (either by the engine
516 // directly or via zscript) only last until the next area is loaded (via loadscr).
517
518 // Returns the screen containing the (x, y) world position.
519 1632988818 mapscr* get_scr_for_world_xy(int x, int y)
520 {
521 // Quick path, but should work the same without.
522
2/2
✓ Branch 0 taken 1621856658 times.
✓ Branch 1 taken 11132160 times.
1632988818 if (!is_in_scrolling_region()) return origin_scr;
523 11132160 return get_scr(get_screen_for_world_xy(x, y));
524 1632988818 }
525
526 24481523 mapscr* get_scr_for_rpos(rpos_t rpos)
527 {
528 // Quick path, but should work the same without.
529
2/2
✓ Branch 0 taken 24343577 times.
✓ Branch 1 taken 137946 times.
24481523 if (!is_in_scrolling_region()) return origin_scr;
530 137946 return get_scr(get_screen_for_rpos(rpos));
531 24481523 }
532
533 14 mapscr* get_scr_for_rpos_layer(rpos_t rpos, int layer)
534 {
535 14 return get_scr_layer(get_screen_for_rpos(rpos), layer);
536 }
537
538 // Note: layer=0 is the base screen, 1 is the first layer, etc.
539 2306005831 mapscr* get_scr_for_world_xy_layer(int x, int y, int layer)
540 {
541 DCHECK_LAYER_ZERO_INDEX(layer);
542
2/2
✓ Branch 0 taken 2294588353 times.
✓ Branch 1 taken 11417478 times.
2306005831 if (!is_in_scrolling_region()) return get_scr_layer(cur_screen, layer);
543
2/2
✓ Branch 0 taken 708094 times.
✓ Branch 1 taken 10709384 times.
11417478 return layer == 0 ?
544 708094 get_scr_for_world_xy(x, y) :
545 10709384 get_scr_layer(get_screen_for_world_xy(x, y), layer);
546 2306005831 }
547
548 1831378874 int get_region_screen_offset(int screen)
549 {
550 1831378874 return get_region_relative_dx(screen) + get_region_relative_dy(screen) * cur_region.screen_width;
551 }
552
553 654673804 int get_screen_for_region_index_offset(int offset)
554 {
555 654673804 int scr_dx = offset % cur_region.screen_width;
556 654673804 int scr_dy = offset / cur_region.screen_width;
557 654673804 int screen = cur_screen + scr_dx + scr_dy*16;
558 654673804 return screen;
559 }
560
561 654489967 mapscr* get_scr_for_region_index_offset(int offset)
562 {
563 654489967 int screen = get_screen_for_region_index_offset(offset);
564 654489967 return get_scr(screen);
565 }
566
567 // The screen at (map, screen) must exist.
568 1418252933 mapscr* get_scr(int map, int screen)
569 {
570 1418252933 mapscr* scr = get_scr_maybe(map, screen);
571
1/2
✓ Branch 0 taken 1418252933 times.
✗ Branch 1 not taken.
1418252933 CHECK(scr);
572 1418252933 return scr;
573 }
574
575 836186365 mapscr* get_scr(int screen)
576 {
577 836186365 return get_scr(cur_map, screen);
578 }
579
580 // Returns null if active screen does not exist.
581 1447797700 mapscr* get_scr_maybe(int map, int screen)
582 {
583 DCHECK_RANGE_INCLUSIVE(screen, 0, 135);
584
585
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1447797700 times.
1447797700 if (map == cur_map)
586 {
587
2/2
✓ Branch 0 taken 1427024756 times.
✓ Branch 1 taken 20772944 times.
1447797700 if (screen == cur_screen)
588 1427024756 return origin_scr;
589
590 20772944 int index = screen*7;
591
2/2
✓ Branch 0 taken 20761854 times.
✓ Branch 1 taken 11090 times.
20772944 if (temporary_screens[index])
592 20761854 return temporary_screens[index];
593
594
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (screen == home_screen)
595 return special_warp_return_scr;
596 11090 }
597
598
3/6
✓ Branch 0 taken 11090 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11090 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11090 times.
11090 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
599 {
600 11090 int index = screen*7;
601
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (FFCore.ScrollingScreensAll[index])
602 11090 return FFCore.ScrollingScreensAll[index];
603 }
604
605 return nullptr;
606 1447797700 }
607
608 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
609 7055760822 mapscr* get_scr_layer(int map, int screen, int layer)
610 {
611 DCHECK_LAYER_ZERO_INDEX(layer);
612
2/2
✓ Branch 0 taken 6475017741 times.
✓ Branch 1 taken 580743081 times.
7055760822 if (layer == 0)
613 580743081 return get_scr(map, screen);
614
615
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6475017741 times.
6475017741 if (map == cur_map)
616 {
617 6475017741 int index = screen*7 + layer;
618
2/2
✓ Branch 0 taken 6474949341 times.
✓ Branch 1 taken 68400 times.
6475017741 if (temporary_screens[index])
619 6474949341 return temporary_screens[index];
620
621
2/2
✓ Branch 0 taken 1860 times.
✓ Branch 1 taken 66540 times.
68400 if (screen == home_screen)
622 1860 return &special_warp_return_scrs[layer];
623 66540 }
624
625
1/2
✓ Branch 0 taken 66540 times.
✗ Branch 1 not taken.
66540 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
626 {
627 66540 int index = screen*7 + layer;
628
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66540 times.
66540 if (FFCore.ScrollingScreensAll[index])
629 66540 return FFCore.ScrollingScreensAll[index];
630 }
631
632 NOTREACHED();
633 7055760822 }
634
635 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
636 6657108249 mapscr* get_scr_layer(int screen, int layer)
637 {
638 6657108249 return get_scr_layer(cur_map, screen, layer);
639 }
640
641 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
642 // Return nullptr if screen is not valid.
643 396578848 mapscr* get_scr_layer_valid(int screen, int layer)
644 {
645
2/2
✓ Branch 0 taken 77993567 times.
✓ Branch 1 taken 318585281 times.
396578848 if (mapscr* scr = get_scr_layer(cur_map, screen, layer); scr->is_valid())
646 77993567 return scr;
647 318585281 return nullptr;
648 396578848 }
649
650 401 mapscr* get_scr_current_region_dir(int screen, direction dir)
651 {
652 401 int x = get_region_relative_dx(screen);
653 401 int y = get_region_relative_dy(screen);
654
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
401 if (dir == left && x == 0)
655 71 return nullptr;
656
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
330 if (dir == right && x == 15)
657 return nullptr;
658
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
330 if (dir == down && y == 7)
659 return nullptr;
660
3/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
330 if (dir == up && y == 0)
661 189 return nullptr;
662
663 141 screen = screen_index_direction(screen, dir);
664
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (is_in_current_region(screen))
665 return get_scr(screen);
666
667 141 return nullptr;
668 401 }
669
670 183837 ffc_handle_t get_ffc_handle(ffc_id_t id)
671 {
672 183837 uint8_t screen = get_screen_for_region_index_offset(id / MAXFFCS);
673 183837 uint8_t i = id % MAXFFCS;
674 183837 mapscr* scr = get_scr(screen);
675 183837 ffcdata* ffc = &scr->getFFC(id % MAXFFCS);
676 183837 return {scr, screen, id, i, ffc};
677 }
678
679 34566 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen, int x, int y)
680 {
681 34566 x += get_region_relative_dx(screen) * 256;
682 34566 y += get_region_relative_dy(screen) * 176;
683 34566 return {x, y};
684 }
685
686 1049392 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen)
687 {
688 1049392 int x = get_region_relative_dx(screen) * 256;
689 1049392 int y = get_region_relative_dy(screen) * 176;
690 1049392 return {x, y};
691 }
692
693 12124901736 int32_t COMBOPOS(int32_t x, int32_t y)
694 {
695 DCHECK(x >= 0 && x < 256 && y >= 0 && y < 176);
696 12124901736 return (y & 0xF0) + (x >> 4);
697 }
698 int32_t COMBOPOS_B(int32_t x, int32_t y)
699 {
700 if(unsigned(x) >= 256 || unsigned(y) >= 176)
701 return -1;
702 return (y & 0xF0) + (x >> 4);
703 }
704 3323906910 int32_t COMBOX(int32_t pos)
705 {
706 3323906910 return pos % 16 * 16;
707 }
708 3323906910 int32_t COMBOY(int32_t pos)
709 {
710 3323906910 return pos & 0xF0;
711 }
712
713 112491539 rpos_t COMBOPOS_REGION(int32_t x, int32_t y)
714 {
715
2/2
✓ Branch 0 taken 83938893 times.
✓ Branch 1 taken 28552646 times.
112491539 if (!is_in_scrolling_region())
716 83938893 return (rpos_t) COMBOPOS(x, y);
717
718 DCHECK(is_in_world_bounds(x, y));
719 28552646 int scr_dx = x / (16*16);
720 28552646 int scr_dy = y / (11*16);
721 28552646 int pos = COMBOPOS(x%256, y%176);
722 28552646 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
723 112491539 }
724 6295880580 rpos_t COMBOPOS_REGION_B(int32_t x, int32_t y)
725 {
726
2/2
✓ Branch 0 taken 1397544 times.
✓ Branch 1 taken 6294483036 times.
6295880580 if (!is_in_world_bounds(x, y))
727 1397544 return rpos_t::None;
728
729 6294483036 int scr_dx = x / (16*16);
730 6294483036 int scr_dy = y / (11*16);
731 6294483036 int pos = COMBOPOS(x%256, y%176);
732 6294483036 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
733 6295880580 }
734 21451966 std::pair<int32_t, int32_t> COMBOXY_REGION(rpos_t rpos)
735 {
736 21451966 int scr_index = static_cast<int32_t>(rpos) / 176;
737 21451966 int scr_dx = scr_index % cur_region.screen_width;
738 21451966 int scr_dy = scr_index / cur_region.screen_width;
739 21451966 int pos = RPOS_TO_POS(rpos);
740 21451966 int x = scr_dx*16*16 + COMBOX(pos);
741 21451966 int y = scr_dy*11*16 + COMBOY(pos);
742 21451966 return {x, y};
743 }
744 60396 int32_t COMBOX_REGION(rpos_t rpos)
745 {
746 60396 auto [x, y] = COMBOXY_REGION(rpos);
747 60396 return x;
748 }
749 12225 int32_t COMBOY_REGION(rpos_t rpos)
750 {
751 12225 auto [x, y] = COMBOXY_REGION(rpos);
752 12225 return y;
753 }
754
755 70177 rpos_t COMBOPOS_REGION_INDEX(int32_t x, int32_t y)
756 {
757 DCHECK(is_in_world_bounds(x, y));
758
1/2
✓ Branch 0 taken 70177 times.
✗ Branch 1 not taken.
70177 if (!is_in_scrolling_region())
759 70177 return (rpos_t)(x + y * 16);
760
761 int scr_dx = x / 16;
762 int scr_dy = y / 11;
763 x %= 16;
764 y %= 11;
765 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + x + y * 16);
766 70177 }
767 70632 std::pair<int32_t, int32_t> COMBOXY_REGION_INDEX(rpos_t rpos)
768 {
769 70632 int scr_index = static_cast<int32_t>(rpos) / 176;
770 70632 int scr_dx = scr_index % cur_region.screen_width;
771 70632 int scr_dy = scr_index / cur_region.screen_width;
772 70632 int pos = RPOS_TO_POS(rpos);
773 70632 int x = scr_dx*16 + pos%16;
774 70632 int y = scr_dy*11 + pos/16;
775 70632 return {x, y};
776 }
777
778 553576702 int32_t mapind(int32_t map, int32_t scr)
779 {
780 553576702 return map * MAPSCRSNORMAL + scr;
781 }
782
783 FONT *get_zc_font(int index);
784
785 extern sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations;
786 extern movingblock mblock2; //mblock[4]?
787 extern portal mirror_portal;
788
789 void Z_message_d(const char *format,...)
790 {
791 #ifdef _DEBUG
792 char buf[512];
793 va_list ap;
794 va_start(ap, format);
795 vsprintf(buf, format, ap);
796 va_end(ap);
797
798 al_trace("%s",buf);
799 #else
800 format=format;
801 #endif
802 }
803
804
805
806 bool checktrigger=false;
807
808 void debugging_box(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
809 {
810 //reference/optimization: the start of the unused drawing command index can now be queried. -Gleeok
811 int32_t index = script_drawing_commands.GetNext();
812
813 if(index < 0)
814 return;
815
816 int32_t *sdci = &script_drawing_commands[index][0];
817
818 sdci[0] = RECTR;
819 sdci[1] = 30000;
820 sdci[2] = x1*10000;
821 sdci[3] = y1*10000;
822 sdci[4] = x2*10000;
823 sdci[5] = y2*10000;
824 sdci[6] = 10000;
825 sdci[7] = 10000;
826 sdci[8] = 0;
827 sdci[9] = 0;
828 sdci[10] = 0;
829 sdci[11] = 10000;
830 sdci[12] = 1280000;
831 }
832
833 void clear_dmap(word i)
834 {
835 DMaps[i].clear();
836 }
837
838 void clear_dmaps()
839 {
840 for(int32_t i=0; i<MAXDMAPS; i++)
841 {
842 clear_dmap(i);
843 }
844 }
845
846 223418082 int32_t isdungeon(int32_t dmap, int32_t screen)
847 {
848
2/2
✓ Branch 0 taken 223372402 times.
✓ Branch 1 taken 45680 times.
223418082 if (dmap < 0) dmap = cur_dmap;
849
850 // dungeons can have any dlevel above 0
851
2/2
✓ Branch 0 taken 122175146 times.
✓ Branch 1 taken 101242936 times.
223418082 if((DMaps[dmap].type&dmfTYPE) == dmDNGN)
852 {
853
2/2
✓ Branch 0 taken 9961 times.
✓ Branch 1 taken 101232975 times.
101242936 if (get_canonical_scr(cur_map, screen)->flags6&fCAVEROOM)
854 9961 return 0;
855
856 101232975 return 1;
857 }
858
859 // dlevels that aren't dungeons are caves
860
2/2
✓ Branch 0 taken 36827 times.
✓ Branch 1 taken 122138319 times.
122175146 if (get_canonical_scr(cur_map, screen)->flags6&fDUNGEONROOM)
861 36827 return 1;
862
863 122138319 return 0;
864 223418082 }
865
866 39924269 int32_t isdungeon(int32_t screen)
867 {
868 39924269 return isdungeon(cur_dmap, screen);
869 }
870
871 183366931 int32_t isdungeon()
872 {
873 183366931 return isdungeon(cur_dmap, hero_screen);
874 }
875
876 88901 bool canPermSecret(int32_t dmap, int32_t screen)
877 {
878
2/2
✓ Branch 0 taken 13909 times.
✓ Branch 1 taken 74992 times.
88901 return (!isdungeon(dmap, screen) || get_qr(qr_DUNGEON_DMAPS_PERM_SECRETS));
879 }
880
881 1375013342 int32_t MAPCOMBO(int32_t x, int32_t y)
882 {
883 1375013342 x = vbound(x, 0, world_w-1);
884 1375013342 y = vbound(y, 0, world_h-1);
885 1375013342 int pos = COMBOPOS(x%256, y%176);
886 1375013342 mapscr* scr = get_scr_for_world_xy(x, y);
887 1375013342 return scr->data[pos];
888 }
889
890 //specific layers 1 to 6
891 1709359105 int32_t MAPCOMBOL(int32_t layer,int32_t x,int32_t y)
892 {
893 DCHECK(layer >= 1 && layer <= 6);
894
3/4
✓ Branch 0 taken 1688992147 times.
✓ Branch 1 taken 20366958 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1688992147 times.
1709359105 if (!is_in_world_bounds(x, y) || layer <= 0)
895 20366958 return 0;
896
897 1688992147 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
898
2/2
✓ Branch 0 taken 495997682 times.
✓ Branch 1 taken 1192994465 times.
1688992147 if (!m->is_valid())
899 1192994465 return 0;
900
901 495997682 int pos = COMBOPOS(x%256, y%176);
902 495997682 return m->data[pos];
903 1709359105 }
904
905 int32_t MAPCSETL(int32_t layer,int32_t x,int32_t y)
906 {
907 DCHECK(layer >= 1 && layer <= 6);
908 if (!is_in_world_bounds(x, y) || layer <= 0)
909 return 0;
910
911 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
912 if (!m->is_valid())
913 return 0;
914
915 int pos = COMBOPOS(x%256, y%176);
916 return m->cset[pos];
917 }
918
919 189084 int32_t MAPFLAGL(int32_t layer,int32_t x,int32_t y)
920 {
921 DCHECK(layer >= 1 && layer <= 6);
922
2/4
✓ Branch 0 taken 189084 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189084 times.
189084 if (!is_in_world_bounds(x, y) || layer <= 0)
923 return 0;
924
925 189084 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
926
2/2
✓ Branch 0 taken 148690 times.
✓ Branch 1 taken 40394 times.
189084 if (!m->is_valid())
927 40394 return 0;
928
929 148690 int pos = COMBOPOS(x%256, y%176);
930 148690 return m->sflag[pos];
931 189084 }
932
933 6281 int32_t COMBOTYPEL(int32_t layer,int32_t x,int32_t y)
934 {
935 DCHECK(layer >= 1 && layer <= 6);
936
2/4
✓ Branch 0 taken 6281 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6281 times.
6281 if (!is_in_world_bounds(x, y) || layer <= 0)
937 return 0;
938
939 6281 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
940
2/2
✓ Branch 0 taken 5809 times.
✓ Branch 1 taken 472 times.
6281 if (!m->is_valid())
941 472 return 0;
942
943 5809 int pos = COMBOPOS(x%256, y%176);
944 5809 return combobuf[m->data[pos]].type;
945 6281 }
946
947 189084 int32_t MAPCOMBOFLAGL(int32_t layer,int32_t x,int32_t y)
948 {
949 DCHECK(layer >= 1 && layer <= 6);
950
2/4
✓ Branch 0 taken 189084 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189084 times.
189084 if (!is_in_world_bounds(x, y) || layer <= 0)
951 return 0;
952
953 189084 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
954
2/2
✓ Branch 0 taken 148690 times.
✓ Branch 1 taken 40394 times.
189084 if (!m->is_valid())
955 40394 return 0;
956
957 148690 int pos = COMBOPOS(x%256, y%176);
958 148690 return combobuf[m->data[pos]].flag;
959 189084 }
960
961
962 // True if the FFC covers x, y and is not ethereal or a changer.
963 2467220443 bool ffcIsAt(const ffc_handle_t& ffc_handle, int32_t x, int32_t y)
964 {
965
2/2
✓ Branch 0 taken 746693882 times.
✓ Branch 1 taken 1720526561 times.
2467220443 if (ffc_handle.data()<=0)
966 746693882 return false;
967
968
2/2
✓ Branch 0 taken 300864173 times.
✓ Branch 1 taken 1419662388 times.
1720526561 if((ffc_handle.ffc->flags&(ffc_changer|ffc_ethereal))!=0)
969 300864173 return false;
970
971 1419662388 int32_t fx=ffc_handle.ffc->x.getInt();
972
4/4
✓ Branch 0 taken 976145039 times.
✓ Branch 1 taken 443517349 times.
✓ Branch 2 taken 866031149 times.
✓ Branch 3 taken 110113890 times.
1419662388 if(x<fx || x>fx+(ffc_handle.scr->ffEffectWidth(ffc_handle.i)-1)) // FFC sizes are weird.
973 1309548498 return false;
974
975 110113890 int32_t fy=ffc_handle.ffc->y.getInt();
976
4/4
✓ Branch 0 taken 80134228 times.
✓ Branch 1 taken 29979662 times.
✓ Branch 2 taken 60068352 times.
✓ Branch 3 taken 20065876 times.
110113890 if(y<fy || y>fy+(ffc_handle.scr->ffEffectHeight(ffc_handle.i)-1))
977 90048014 return false;
978
979 20065876 return true;
980 2467220443 }
981
982 998864676 int32_t MAPFFCOMBO(int32_t x,int32_t y)
983 {
984
2/2
✓ Branch 0 taken 13161741 times.
✓ Branch 1 taken 985702935 times.
998864676 if (auto ffc_handle = getFFCAt(x, y))
985 13161741 return ffc_handle->data();
986 985702935 return 0;
987 998864676 }
988
989 207232 int32_t MAPCSET(int32_t x, int32_t y)
990 {
991
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207232 times.
207232 if (!is_in_world_bounds(x, y))
992 return 0;
993 207232 mapscr* scr = get_scr_for_world_xy(x, y);
994 207232 int pos = COMBOPOS(x%256, y%176);
995 207232 return scr->cset[pos];
996 207232 }
997
998 73651503 int32_t MAPFLAG(int32_t x, int32_t y)
999 {
1000
2/2
✓ Branch 0 taken 28140 times.
✓ Branch 1 taken 73623363 times.
73651503 if (!is_in_world_bounds(x, y))
1001 28140 return 0;
1002 73623363 mapscr* scr = get_scr_for_world_xy(x, y);
1003 73623363 int pos = COMBOPOS(x%256, y%176);
1004 73623363 return scr->sflag[pos];
1005 73651503 }
1006
1007 165692612 int32_t COMBOTYPE(int32_t x,int32_t y)
1008 {
1009 165692612 int32_t b=1;
1010
2/2
✓ Branch 0 taken 96754421 times.
✓ Branch 1 taken 68938191 times.
165692612 if(x&8) b<<=2;
1011
2/2
✓ Branch 0 taken 83455899 times.
✓ Branch 1 taken 82236713 times.
165692612 if(y&8) b<<=1;
1012
1013
2/2
✓ Branch 0 taken 331378186 times.
✓ Branch 1 taken 165685574 times.
497063760 for (int32_t i = 0; i <= 1; ++i)
1014 {
1015
2/2
✓ Branch 0 taken 320233226 times.
✓ Branch 1 taken 11144960 times.
331378186 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1016 {
1017
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 320233226 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
320233226 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x, y, i)) return cNONE;
1018 320233226 }
1019 else
1020 {
1021
4/4
✓ Branch 0 taken 10190 times.
✓ Branch 1 taken 11134770 times.
✓ Branch 2 taken 3152 times.
✓ Branch 3 taken 7038 times.
11144960 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x, y, i)) return cNONE;
1022 }
1023 331371148 }
1024
1025 165685574 newcombo const& cmb = combobuf[MAPCOMBO(x,y)];
1026
5/6
✓ Branch 0 taken 3652644 times.
✓ Branch 1 taken 162032930 times.
✓ Branch 2 taken 3069708 times.
✓ Branch 3 taken 582936 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3069708 times.
165685574 if (cmb.type == cWATER && (cmb.walk&b) && ((cmb.walk>>4)&b))
1027 {
1028
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3069708 times.
3069708 if(cmb.usrflags&cflag4) return cSHALLOWWATER;
1029
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3069708 times.
3069708 if(cmb.usrflags&cflag3) return cNONE;
1030 3069708 }
1031 165685574 return cmb.type;
1032 165692612 }
1033
1034 50218236 int32_t FFCOMBOTYPE(int32_t x,int32_t y)
1035 {
1036 50218236 return combobuf[MAPFFCOMBO(x,y)].type;
1037 }
1038
1039 4915492 int32_t FFORCOMBO(int32_t x, int32_t y)
1040 {
1041
2/2
✓ Branch 0 taken 58516 times.
✓ Branch 1 taken 4856976 times.
4915492 if (auto ffc_handle = getFFCAt(x, y))
1042 58516 return ffc_handle->data();
1043
1044 4856976 return MAPCOMBO(x,y);
1045 4915492 }
1046
1047 int32_t FFORCOMBOTYPE(int32_t x, int32_t y)
1048 {
1049 for (int32_t i = 0; i <= 1; ++i)
1050 {
1051 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1052 {
1053 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1054 }
1055 else
1056 {
1057 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1058 }
1059 }
1060 int32_t b=1;
1061
1062 if(x&8) b<<=2;
1063
1064 if(y&8) b<<=1;
1065 newcombo const& cmb = combobuf[FFORCOMBO(x,y)];
1066 if (cmb.type == cWATER && (cmb.usrflags&cflag4) && (cmb.walk&b)) return cSHALLOWWATER;
1067 if (cmb.type == cWATER && (cmb.usrflags&cflag3) && (cmb.walk&b)) return cNONE;
1068 return cmb.type;
1069 }
1070
1071 int32_t FFORCOMBO_L(int32_t layer, int32_t x, int32_t y)
1072 {
1073 if (auto ffc_handle = getFFCAt(x, y))
1074 return ffc_handle->data();
1075
1076 return layer ? MAPCOMBOL(layer, x, y) : MAPCOMBO(x,y);
1077 }
1078
1079 int32_t FFORCOMBOTYPE_L(int32_t layer, int32_t x, int32_t y)
1080 {
1081 return combobuf[FFORCOMBO_L(layer,x,y)].type;
1082 }
1083
1084 70141903 int32_t MAPCOMBOFLAG(int32_t x,int32_t y)
1085 {
1086
2/2
✓ Branch 0 taken 27852 times.
✓ Branch 1 taken 70114051 times.
70141903 if (!is_in_world_bounds(x, y))
1087 27852 return 0;
1088
1089 70114051 mapscr* scr = get_scr_for_world_xy(x, y);
1090 70114051 int pos = COMBOPOS(x%256, y%176);
1091 70114051 return combobuf[scr->data[pos]].flag;
1092 70141903 }
1093
1094 56824297 int32_t MAPFFCOMBOFLAG(int32_t x,int32_t y)
1095 {
1096
2/2
✓ Branch 0 taken 746177 times.
✓ Branch 1 taken 56078120 times.
56824297 if (auto ffc_handle = getFFCAt(x, y))
1097 746177 return ffc_handle->cflag();
1098
1099 56078120 return 0;
1100 56824297 }
1101
1102 1312440719 std::optional<ffc_handle_t> getFFCAt(int32_t x, int32_t y)
1103 {
1104 2787964844 return find_ffc([&](const ffc_handle_t& ffc_handle) {
1105 1475524125 return ffcIsAt(ffc_handle, x, y);
1106 });
1107 }
1108
1109 3044 int32_t MAPCOMBO(const rpos_handle_t& rpos_handle)
1110 {
1111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3044 times.
3044 if (!rpos_handle.scr->is_valid()) return 0;
1112 3044 return rpos_handle.data();
1113 3044 }
1114
1115 3165515511 int32_t MAPCOMBO2(int32_t layer, int32_t x, int32_t y)
1116 {
1117 DCHECK_LAYER_NEG1_INDEX(layer);
1118
2/2
✓ Branch 0 taken 22433406 times.
✓ Branch 1 taken 3143082105 times.
3165515511 if (!is_in_world_bounds(x, y)) return 0;
1119
2/2
✓ Branch 0 taken 3074262371 times.
✓ Branch 1 taken 68819734 times.
3143082105 if (layer == -1) return MAPCOMBO(x, y);
1120
1121 3074262371 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1122
2/2
✓ Branch 0 taken 2118737102 times.
✓ Branch 1 taken 955525269 times.
3074262371 if (!rpos_handle.scr->is_valid()) return 0;
1123
1124 955525269 return rpos_handle.data();
1125 3165515511 }
1126
1127 15796 static void apply_state_changes_to_screen(mapscr& scr, int32_t map, int32_t screen, int32_t flags, bool secrets_do_replay_comment)
1128 {
1129 15796 auto screen_handles = create_screen_handles_one(&scr);
1130
1131
3/4
✓ Branch 0 taken 535 times.
✓ Branch 1 taken 15261 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 535 times.
15796 if ((flags & mSECRET) && canPermSecret(cur_dmap, screen))
1132 {
1133 535 reveal_hidden_stairs(&scr, screen, false);
1134 535 bool do_layers = false;
1135 535 bool from_active_screen = false;
1136 535 trigger_secrets_for_screen_internal(screen_handles, do_layers, from_active_screen, -3, secrets_do_replay_comment);
1137 535 }
1138
1/2
✓ Branch 0 taken 15796 times.
✗ Branch 1 not taken.
15796 if (flags & mLIGHTBEAM)
1139 {
1140 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
1141 if (rpos_handle.ctype() == cLIGHTTARGET)
1142 {
1143 if (!(rpos_handle.combo().usrflags&cflag1)) //Unlit version
1144 rpos_handle.increment_data();
1145 }
1146 });
1147 }
1148
1149 15796 int lvl = DMaps[cur_dmap].level;
1150 15796 toggle_switches(game->lvlswitches[lvl], true, screen_handles);
1151 15796 toggle_gswitches_load(screen_handles);
1152
1153
2/2
✓ Branch 0 taken 15704 times.
✓ Branch 1 taken 92 times.
15796 if(flags&mLOCKBLOCK) // if special stuff done before
1154 {
1155 92 remove_screenstatecombos2(screen_handles, false, cLOCKBLOCK, cLOCKBLOCK2);
1156 92 }
1157
1158
1/2
✓ Branch 0 taken 15796 times.
✗ Branch 1 not taken.
15796 if(flags&mBOSSLOCKBLOCK) // if special stuff done before
1159 {
1160 remove_screenstatecombos2(screen_handles, false, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
1161 }
1162
1163
1/2
✓ Branch 0 taken 15796 times.
✗ Branch 1 not taken.
15796 if(flags&mCHEST) // if special stuff done before
1164 {
1165 remove_screenstatecombos2(screen_handles, false, cCHEST, cCHEST2);
1166 }
1167
1168
1/2
✓ Branch 0 taken 15796 times.
✗ Branch 1 not taken.
15796 if(flags&mCHEST) // if special stuff done before
1169 {
1170 remove_screenstatecombos2(screen_handles, false, cLOCKEDCHEST, cLOCKEDCHEST2);
1171 }
1172
1173
1/2
✓ Branch 0 taken 15796 times.
✗ Branch 1 not taken.
15796 if(flags&mBOSSCHEST) // if special stuff done before
1174 {
1175 remove_screenstatecombos2(screen_handles, false, cBOSSCHEST, cBOSSCHEST2);
1176 }
1177
1178
1179 15796 int mi = mapind(map, screen);
1180 15796 clear_xdoors_mi(screen_handles, mi);
1181 15796 clear_xstatecombos_mi(screen_handles, mi);
1182
1183 2797652 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
1184 2781856 auto cid = handle.data();
1185 2781856 auto& cmb = handle.combo();
1186
2/4
✓ Branch 0 taken 2781856 times.
✓ Branch 1 taken 41380 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2823236 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
1187 {
1188 41380 auto& trig = cmb.triggers[idx];
1189
1/4
✓ Branch 0 taken 41380 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
41380 if (trig.triggerflags[4] & combotriggerSCREENLOAD)
1190 {
1191 do_trigger_combo(handle, idx);
1192 if(handle.data() != cid) break;
1193 }
1194 41380 }
1195 2781856 });
1196 15796 }
1197
1198 53166 std::optional<mapscr> load_temp_mapscr_and_apply_secrets(int32_t map, int32_t screen, int32_t layer, bool secrets, bool secrets_do_replay_comment)
1199 {
1200
2/4
✓ Branch 0 taken 53166 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53166 times.
53166 if (map < 0 || screen < 0)
1201 return std::nullopt;
1202
1203 53166 const mapscr* source = get_canonical_scr(map, screen);
1204
2/2
✓ Branch 0 taken 40953 times.
✓ Branch 1 taken 12213 times.
53166 if (!source->is_valid())
1205 12213 return std::nullopt;
1206
1207
2/2
✓ Branch 0 taken 8307 times.
✓ Branch 1 taken 32646 times.
40953 if (layer >= 0)
1208 {
1209
2/2
✓ Branch 0 taken 25157 times.
✓ Branch 1 taken 7489 times.
32646 if (source->layermap[layer] <= 0)
1210 25157 return std::nullopt;
1211
1212 7489 source = get_canonical_scr(source->layermap[layer] - 1, source->layerscreen[layer]);
1213
1/2
✓ Branch 0 taken 7489 times.
✗ Branch 1 not taken.
7489 if (!source->is_valid())
1214 return std::nullopt;
1215 7489 }
1216
1217
1/2
✓ Branch 0 taken 15796 times.
✗ Branch 1 not taken.
15796 int flags = secrets ? game->maps[mapind(map, screen)] : 0;
1218 15796 mapscr scr = *source;
1219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15796 times.
15796 apply_state_changes_to_screen(scr, map, screen, flags, secrets_do_replay_comment);
1220
1221 15796 return scr;
1222 53166 }
1223
1224 27203 static int32_t MAPCOMBO3_impl(int32_t map, int32_t screen, int32_t layer, int32_t pos, bool secrets)
1225 {
1226
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if (map < 0 || screen < 0) return 0;
1227
1228
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if(pos>175 || pos < 0)
1229 return 0;
1230
1231 // TODO: consider caching this (invalidate on any modification via scripting, or anything
1232 // `apply_state_changes_to_screen` checks).
1233
4/5
✓ Branch 0 taken 4976 times.
✓ Branch 1 taken 22227 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4976 times.
✓ Branch 4 taken 22227 times.
32179 if (auto s = load_temp_mapscr_and_apply_secrets(map, screen, layer, secrets))
1234 4976 return s->data[pos];
1235
1236 22227 return 0;
1237 27203 }
1238
1239 // Read from the current temporary screens or, if (map, screen) is not loaded,
1240 // load that screen and apply the relevant secrets before evaluating the combo at that position.
1241 136554394 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets)
1242 {
1243 DCHECK_LAYER_NEG1_INDEX(layer);
1244 DCHECK(map >= 0 && screen >= 0);
1245
1246
2/2
✓ Branch 0 taken 136527191 times.
✓ Branch 1 taken 27203 times.
136554394 if (is_in_current_region(map, screen)) return MAPCOMBO2(layer, x, y);
1247
1248 // Screen is not in the current region, so we have to load and trigger some secrets.
1249 27203 int pos = COMBOPOS(x, y);
1250 27203 return MAPCOMBO3_impl(map, screen, layer, pos, secrets);
1251 136554394 }
1252
1253 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, rpos_t rpos, bool secrets)
1254 {
1255 DCHECK_LAYER_NEG1_INDEX(layer);
1256 DCHECK(map >= 0 && screen >= 0);
1257 DCHECK(is_valid_rpos(rpos));
1258
1259 if (is_in_current_region(map, screen)) return MAPCOMBO(get_rpos_handle(rpos, layer + 1));
1260
1261 // Screen is not currently loaded, so we have to load and trigger some secrets.
1262 return MAPCOMBO3_impl(map, screen, layer, RPOS_TO_POS(rpos), secrets);
1263 }
1264
1265 int32_t MAPCSET2(int32_t layer,int32_t x,int32_t y)
1266 {
1267 DCHECK_LAYER_NEG1_INDEX(layer);
1268 if (!is_in_world_bounds(x, y))
1269 return 0;
1270 if (layer == -1) return MAPCSET(x, y);
1271
1272 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1273 if (!rpos_handle.scr->is_valid()) return 0;
1274
1275 return rpos_handle.cset();
1276 }
1277
1278 98886311 int32_t MAPFLAG2(int32_t layer,int32_t x,int32_t y)
1279 {
1280 DCHECK_LAYER_NEG1_INDEX(layer);
1281
3/4
✓ Branch 0 taken 1861685 times.
✓ Branch 1 taken 97024626 times.
✓ Branch 2 taken 1861685 times.
✗ Branch 3 not taken.
98886311 if (!get_qr(qr_BUGGED_LAYERED_FLAGS) && (!is_in_world_bounds(x, y)))
1282 return 0;
1283
2/2
✓ Branch 0 taken 81284683 times.
✓ Branch 1 taken 17601628 times.
98886311 if (layer == -1) return MAPFLAG(x, y);
1284
1285 81284683 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1286
2/2
✓ Branch 0 taken 62992546 times.
✓ Branch 1 taken 18292137 times.
81284683 if (!rpos_handle.scr->is_valid()) return 0;
1287
1288 18292137 return rpos_handle.sflag();
1289 98886311 }
1290
1291 2518104 int32_t COMBOTYPE2(int32_t layer,int32_t x,int32_t y)
1292 {
1293
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2518104 times.
2518104 if(layer < 1)
1294 {
1295
2/2
✓ Branch 0 taken 5036208 times.
✓ Branch 1 taken 2518104 times.
7554312 for (int32_t i = layer+1; i <= 1; ++i)
1296 {
1297
2/2
✓ Branch 0 taken 4212456 times.
✓ Branch 1 taken 823752 times.
5036208 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1298 {
1299
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4212456 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4212456 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1300 4212456 }
1301 else
1302 {
1303
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 823752 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
823752 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1304 }
1305 5036208 }
1306 2518104 }
1307
1/2
✓ Branch 0 taken 2518104 times.
✗ Branch 1 not taken.
2518104 if(layer==-1) return COMBOTYPE(x,y);
1308
1309 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1310 if (!rpos_handle.scr->is_valid()) return 0;
1311
1312 return rpos_handle.ctype();
1313 2518104 }
1314
1315 // Returns the flag for the combo at the given position.
1316 // This is also known as an "inherent flag".
1317 97118292 int32_t MAPCOMBOFLAG2(int32_t layer,int32_t x,int32_t y)
1318 {
1319 DCHECK_LAYER_NEG1_INDEX(layer);
1320
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 97118004 times.
97118292 if (!is_in_world_bounds(x, y))
1321 288 return 0;
1322
2/2
✓ Branch 0 taken 81226602 times.
✓ Branch 1 taken 15891402 times.
97118004 if (layer == -1) return MAPCOMBOFLAG(x, y);
1323
1324 81226602 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1325
2/2
✓ Branch 0 taken 63002459 times.
✓ Branch 1 taken 18224143 times.
81226602 if (!rpos_handle.scr->is_valid()) return 0;
1326
1327 18224143 return rpos_handle.cflag();
1328 97118292 }
1329
1330 11415939 bool HASFLAG(int32_t flag, int32_t layer, rpos_t rpos)
1331 {
1332 DCHECK_LAYER_ZERO_INDEX(layer);
1333 11415939 auto rpos_handle = get_rpos_handle(rpos, layer);
1334
2/2
✓ Branch 0 taken 6344284 times.
✓ Branch 1 taken 5071655 times.
11415939 if (!rpos_handle.scr->is_valid()) return false;
1335
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 5067090 times.
5071655 if (rpos_handle.sflag() == flag) return true;
1336
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 5029385 times.
5067090 if (rpos_handle.cflag() == flag) return true;
1337 5029385 return false;
1338 11415939 }
1339
1340 1666933 bool HASFLAG_ANY(int32_t flag, rpos_t rpos)
1341 {
1342 DCHECK(is_valid_rpos(rpos));
1343
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1666933 times.
1666933 if (rpos > region_max_rpos) return false;
1344
1345
2/2
✓ Branch 0 taken 11415939 times.
✓ Branch 1 taken 1624663 times.
13040602 for(auto q = 0; q < 7; ++q)
1346 {
1347
2/2
✓ Branch 0 taken 42270 times.
✓ Branch 1 taken 11373669 times.
11415939 if(HASFLAG(flag, q, rpos))
1348 42270 return true;
1349 11373669 }
1350 1624663 return false;
1351 1666933 }
1352
1353 const char *screenstate_string[16] =
1354 {
1355 "Door Up", "Door Down", "Door Left", "Door Right", "Item", "Special Item", "No Return",
1356 "Temporary No Return", "Lock Blocks", "Boss Lock Blocks", "Chests", "Locked Chests",
1357 "Boss Locked Chests", "Secrets", "Visited", "Light Beams"
1358 };
1359
1360 34843 void eventlog_mapflags()
1361 {
1362 34843 std::ostringstream oss;
1363
1364 34843 int mi = mapind(cur_map, home_screen);
1365
1/2
✓ Branch 0 taken 34843 times.
✗ Branch 1 not taken.
34843 word g = game->maps[mi] &0x3FFF;
1366
1367
2/4
✓ Branch 0 taken 34843 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 34843 times.
✗ Branch 3 not taken.
34843 oss << fmt::format("Screen ({}, {:02X})", cur_map+1, home_screen);
1368
2/2
✓ Branch 0 taken 7049 times.
✓ Branch 1 taken 27794 times.
34843 if(g) // Main States
1369 {
1370 static const int order[] =
1371 {
1372 mSECRET, mITEM, mSPECIALITEM, mLOCKBLOCK, mBOSSLOCKBLOCK,
1373 mCHEST, mLOCKEDCHEST, mBOSSCHEST,
1374 mDOOR_UP, mDOOR_DOWN, mDOOR_LEFT, mDOOR_RIGHT,
1375 mNEVERRET, mTMPNORET
1376 };
1377
1378
1/2
✓ Branch 0 taken 7049 times.
✗ Branch 1 not taken.
7049 oss << " [";
1379 7049 bool comma = false;
1380
2/2
✓ Branch 0 taken 7049 times.
✓ Branch 1 taken 98686 times.
105735 for(int fl : order)
1381 {
1382
2/2
✓ Branch 0 taken 8967 times.
✓ Branch 1 taken 89719 times.
98686 if(!(g&fl))
1383 89719 continue;
1384 8967 byte ind = byte(log2(double(fl)));
1385
2/2
✓ Branch 0 taken 1918 times.
✓ Branch 1 taken 7049 times.
8967 if(comma)
1386
1/2
✓ Branch 0 taken 1918 times.
✗ Branch 1 not taken.
1918 oss << ", ";
1387
1/2
✓ Branch 0 taken 8967 times.
✗ Branch 1 not taken.
8967 oss << screenstate_string[ind];
1388 8967 comma = true;
1389 }
1390
1/2
✓ Branch 0 taken 7049 times.
✗ Branch 1 not taken.
7049 oss << "]";
1391 7049 }
1392
3/4
✓ Branch 0 taken 34843 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 34811 times.
34843 if(game->xstates[mi]) // ExStates
1393 {
1394
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 oss << " Ex[";
1395 32 bool comma = false;
1396
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 1024 times.
1056 for(byte fl = 0; fl < 32; ++fl)
1397 {
1398
3/4
✓ Branch 0 taken 1024 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 992 times.
1024 if(game->xstates[mi] & (1<<fl))
1399 {
1400
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if(comma)
1401 oss << ", ";
1402
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 oss << int(fl);
1403 32 comma = true;
1404 32 }
1405 1024 }
1406
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 oss << "]";
1407 32 }
1408 { // ExDoors
1409
2/2
✓ Branch 0 taken 34843 times.
✓ Branch 1 taken 139372 times.
174215 for(int q = 0; q < 4; ++q)
1410 {
1411 139372 bool comma = false;
1412
2/4
✓ Branch 0 taken 139372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 139372 times.
✗ Branch 3 not taken.
139372 if(auto v = game->xdoors[mi][q])
1413 {
1414 if(comma)
1415 oss << ",";
1416 else oss << " ExDoor";
1417 oss << "[" << dirstr[q];
1418 for(int fl = 0; fl < 8; ++fl)
1419 if(v & (1<<fl))
1420 oss << " " << int(fl);
1421 oss << "]";
1422 comma = true;
1423 }
1424 139372 }
1425 }
1426
2/4
✓ Branch 0 taken 34843 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 34843 times.
34843 Z_eventlog("%s\n", oss.str().c_str());
1427 34843 }
1428
1429 // set specific flag
1430 5608 void setmapflag(mapscr* scr, int32_t flag)
1431 {
1432
2/2
✓ Branch 0 taken 5595 times.
✓ Branch 1 taken 13 times.
5608 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1433 5608 int mi = mapind(cur_map, scr->screen);
1434 5608 setmapflag_mi(scr, mi, flag);
1435 5608 }
1436 57 void setmapflag_homescr(int32_t flag)
1437 {
1438 57 int mi = mapind(cur_map, home_screen);
1439 57 setmapflag_mi(origin_scr, mi, flag);
1440 57 }
1441 2023 void setmapflag_mi(int32_t mi, int32_t flag)
1442 {
1443 2023 byte cscr = mi&((1<<7)-1);
1444 2023 byte cmap = (mi>>7);
1445 2023 mapscr* scr = origin_scr;
1446
2/2
✓ Branch 0 taken 834 times.
✓ Branch 1 taken 1189 times.
2023 if (is_in_current_region(cmap, cscr))
1447 1189 scr = get_scr(cmap, cscr);
1448
1449 2023 setmapflag_mi(scr, mi, flag);
1450 2023 }
1451
1452 8459 static void log_state_change(int map, int screen, std::string action)
1453 {
1454
6/6
✓ Branch 0 taken 1911 times.
✓ Branch 1 taken 6548 times.
✓ Branch 2 taken 994 times.
✓ Branch 3 taken 917 times.
✓ Branch 4 taken 352 times.
✓ Branch 5 taken 642 times.
8459 if (is_in_current_region(map, screen) || (map == cur_map && screen == home_screen))
1455 6900 Z_eventlog("[Map %d, Screen %02X (current)] %s\n", map + 1, screen, action.c_str());
1456 else
1457 1559 Z_eventlog("[Map %d, Screen %02X] %s\n", map + 1, screen, action.c_str());
1458 8459 }
1459
1460 7688 void setmapflag_mi(mapscr* scr, int32_t mi, int32_t flag)
1461 {
1462 7688 byte cscr = mi&((1<<7)-1);
1463 7688 byte cmap = (mi>>7);
1464
1465 7688 float temp=log2((float)flag);
1466
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7688 times.
7688 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1467
1468
3/4
✓ Branch 0 taken 7688 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1552 times.
✓ Branch 3 taken 6136 times.
7688 if (replay_is_active() && !(game->maps[mi] & flag))
1469
1/2
✓ Branch 0 taken 6136 times.
✗ Branch 1 not taken.
6136 replay_step_comment(fmt::format("map {} scr {} flag {}", cmap, cscr, state_string));
1470 7688 game->maps[mi] |= flag;
1471
1/2
✓ Branch 0 taken 7688 times.
✗ Branch 1 not taken.
7688 log_state_change(cmap, cscr, fmt::format("State set: {}", state_string));
1472
1473
10/10
✓ Branch 0 taken 5451 times.
✓ Branch 1 taken 2237 times.
✓ Branch 2 taken 3614 times.
✓ Branch 3 taken 1837 times.
✓ Branch 4 taken 3031 times.
✓ Branch 5 taken 583 times.
✓ Branch 6 taken 2877 times.
✓ Branch 7 taken 154 times.
✓ Branch 8 taken 13 times.
✓ Branch 9 taken 2480 times.
10181 if(flag==mSECRET||flag==mITEM||flag==mSPECIALITEM||flag==mLOCKBLOCK||
1474
6/6
✓ Branch 0 taken 2830 times.
✓ Branch 1 taken 47 times.
✓ Branch 2 taken 2685 times.
✓ Branch 3 taken 145 times.
✓ Branch 4 taken 2493 times.
✓ Branch 5 taken 192 times.
2877 flag==mBOSSLOCKBLOCK||flag==mCHEST||flag==mBOSSCHEST||flag==mLOCKEDCHEST)
1475 {
1476 5208 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1477 5208 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1478
1479 5208 std::vector<int32_t> done;
1480
2/2
✓ Branch 0 taken 5093 times.
✓ Branch 1 taken 115 times.
5208 bool looped = (nmap==cmap+1 && nscr==cscr);
1481
1482
6/6
✓ Branch 0 taken 538 times.
✓ Branch 1 taken 5156 times.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 486 times.
✓ Branch 4 taken 486 times.
✓ Branch 5 taken 5208 times.
5694 while((nmap!=0) && !looped && !(nscr>=128))
1483 {
1484
5/6
✓ Branch 0 taken 364 times.
✓ Branch 1 taken 122 times.
✓ Branch 2 taken 364 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 171 times.
✓ Branch 5 taken 193 times.
486 if((scr->nocarry&flag)!=flag && !(game->maps[((nmap-1)<<7)+nscr] & flag))
1485 {
1486
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 log_state_change(nmap, nscr, "State change carried over");
1487
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 if (replay_is_active())
1488
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 replay_step_comment(fmt::format("map {} scr {} flag {} carry", nmap, nscr, state_string));
1489
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 game->maps[((nmap-1)<<7)+nscr] |= flag;
1490 193 }
1491
1492 486 cmap=nmap;
1493 486 cscr=nscr;
1494 486 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1495 486 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1496
1497
2/2
✓ Branch 0 taken 1480 times.
✓ Branch 1 taken 486 times.
1966 for(auto it = done.begin(); it != done.end(); it++)
1498 {
1499
2/2
✓ Branch 0 taken 1428 times.
✓ Branch 1 taken 52 times.
1480 if(*it == ((nmap-1)<<7)+nscr)
1500 52 looped = true;
1501 1480 }
1502
1503
1/2
✓ Branch 0 taken 486 times.
✗ Branch 1 not taken.
486 done.push_back(((nmap-1)<<7)+nscr);
1504 }
1505 5208 }
1506 7688 }
1507
1508 void unsetmapflag_home(int32_t flag, bool anyflag)
1509 {
1510 int mi = mapind(cur_map, home_screen);
1511 unsetmapflag_mi(origin_scr, mi, flag, anyflag);
1512 }
1513
1514 void unsetmapflag(mapscr* scr, int32_t flag, bool anyflag)
1515 {
1516 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1517 int mi = mapind(cur_map, scr->screen);
1518 unsetmapflag_mi(scr, mi, flag, anyflag);
1519 }
1520
1521 471 void unsetmapflag_mi(int32_t mi, int32_t flag, bool anyflag)
1522 {
1523 471 byte cscr = mi&((1<<7)-1);
1524 471 byte cmap = (mi>>7);
1525 471 mapscr* scr = origin_scr;
1526
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if (is_in_current_region(cmap, cscr))
1527 11 scr = get_scr(cmap, cscr);
1528
1529 471 unsetmapflag_mi(scr, mi, flag, anyflag);
1530 471 }
1531
1532 471 void unsetmapflag_mi(mapscr* scr, int32_t mi, int32_t flag, bool anyflag)
1533 {
1534 471 byte cscr = mi&((1<<7)-1);
1535 471 byte cmap = (mi>>7);
1536
1537
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if(anyflag)
1538 460 game->maps[mi] &= ~flag;
1539
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 else if(flag==mITEM || flag==mSPECIALITEM)
1540 {
1541 if(!(scr->flags4&fNOITEMRESET))
1542 game->maps[mi] &= ~flag;
1543 }
1544 11 else game->maps[mi] &= ~flag;
1545
1546 471 float temp=log2((float)flag);
1547
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1548
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 log_state_change(cmap, cscr, fmt::format("State unset: {}", state_string));
1549
1550
5/10
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 460 times.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 11 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
471 if(flag==mSECRET||flag==mITEM||flag==mSPECIALITEM||flag==mLOCKBLOCK||
1551
4/6
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 5 times.
11 flag==mBOSSLOCKBLOCK||flag==mCHEST||flag==mBOSSCHEST||flag==mLOCKEDCHEST)
1552 {
1553 471 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1554 471 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1555
1556 471 std::vector<int32_t> done;
1557
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 5 times.
471 bool looped = (nmap==cmap+1 && nscr==cscr);
1558
1559
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 471 times.
555 while((nmap!=0) && !looped && !(nscr>=128))
1560 {
1561
4/6
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 84 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 72 times.
84 if((scr->nocarry&flag)!=flag && (game->maps[((nmap-1)<<7)+nscr] & flag))
1562 {
1563
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 log_state_change(nmap, nscr, "State change carried over");
1564
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 game->maps[((nmap-1)<<7)+nscr] &= ~flag;
1565 72 }
1566
1567 84 cmap=nmap;
1568 84 cscr=nscr;
1569 84 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1570 84 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1571
1572
2/2
✓ Branch 0 taken 546 times.
✓ Branch 1 taken 84 times.
630 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1573 {
1574
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 6 times.
546 if(*it == ((nmap-1)<<7)+nscr)
1575 6 looped = true;
1576 546 }
1577
1578
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 done.push_back(((nmap-1)<<7)+nscr);
1579 }
1580 471 }
1581 471 }
1582
1583 44151379 bool getmapflag(int32_t screen, int32_t flag)
1584 {
1585
2/2
✓ Branch 0 taken 1164399 times.
✓ Branch 1 taken 42986980 times.
44151379 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1586 44151379 return (game->maps[mi] & flag) != 0;
1587 }
1588 162323 bool getmapflag(mapscr* scr, int32_t flag)
1589 {
1590 162323 return getmapflag(scr->screen, flag);
1591 }
1592
1593 33 void setxmapflag(int32_t screen, uint32_t flag)
1594 {
1595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
33 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1596 33 setxmapflag_mi(mi, flag);
1597 33 }
1598 35 void setxmapflag_mi(int32_t mi, uint32_t flag)
1599 {
1600
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
35 if(game->xstates[mi] & flag) return;
1601 35 byte cscr = mi&((1<<7)-1);
1602 35 byte cmap = (mi>>7);
1603
1604 35 byte temp=(byte)log2((double)flag);
1605
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 log_state_change(cmap, cscr, fmt::format("ExtraState set: {}", temp));
1606
1607 35 game->xstates[mi] |= flag;
1608 35 }
1609 void unsetxmapflag(int32_t screen, uint32_t flag)
1610 {
1611 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1612 unsetxmapflag_mi(mi, flag);
1613 }
1614 void unsetxmapflag_mi(int32_t mi, uint32_t flag)
1615 {
1616 if(!(game->xstates[mi] & flag)) return;
1617 byte cscr = mi&((1<<7)-1);
1618 byte cmap = (mi>>7);
1619 byte temp=(byte)log2((double)flag);
1620 log_state_change(cmap, cscr, fmt::format("ExtraState unset: {}", temp));
1621 game->xstates[mi] &= ~flag;
1622 }
1623 49 bool getxmapflag(int32_t screen, uint32_t flag)
1624 {
1625
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
49 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1626 49 return getxmapflag_mi(mi, flag);
1627 }
1628 471118847 bool getxmapflag_mi(int32_t mi, uint32_t flag)
1629 {
1630 471118847 return (game->xstates[mi] & flag) != 0;
1631 }
1632
1633 void setxdoor_mi(uint mi, uint dir, uint ind, bool state)
1634 {
1635 if(mi > game->xdoors.size() || dir > 3 || ind > 8)
1636 return;
1637 if(!(game->xdoors[mi][dir] & (1<<ind)) == !state)
1638 return;
1639
1640 SETFLAG(game->xdoors[mi][dir], 1<<ind, state);
1641
1642 int cscr = mi % MAPSCRSNORMAL;
1643 int cmap = mi / MAPSCRSNORMAL;
1644 if (state)
1645 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] set", dirstr[dir], ind));
1646 else
1647 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] unset", dirstr[dir], ind));
1648 }
1649 471118784 bool getxdoor_mi(uint mi, uint dir, uint ind)
1650 {
1651
5/6
✓ Branch 0 taken 471118784 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2582048 times.
✓ Branch 3 taken 468536736 times.
✓ Branch 4 taken 1936536 times.
✓ Branch 5 taken 645512 times.
471118784 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1652 470473272 return false;
1653 645512 return (game->xdoors[mi][dir] & (1<<ind));
1654 471118784 }
1655 bool getxdoor(int32_t screen, uint dir, uint ind)
1656 {
1657 int mi = mapind(cur_map, screen);
1658 return getxdoor_mi(mi,dir,ind);
1659 }
1660
1661 401 void set_doorstate_mi(uint mi, uint dir)
1662 {
1663
1/2
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
401 if(dir >= 4)
1664 return;
1665 401 setmapflag_mi(mi, mDOOR_UP << dir);
1666
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if(auto di = nextscr_mi(mi, dir))
1667 400 setmapflag_mi(*di, mDOOR_UP << oppositeDir[dir]);
1668 401 }
1669 401 void set_doorstate(uint screen, uint dir)
1670 {
1671 401 int mi = mapind(cur_map, screen);
1672 401 set_doorstate_mi(mi, dir);
1673 401 }
1674
1675 void set_xdoorstate_mi(uint mi, uint dir, uint ind)
1676 {
1677 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1678 return;
1679 setxdoor_mi(mi, dir, ind, true);
1680 if(auto di = nextscr_mi(mi, dir))
1681 setxdoor_mi(*di, oppositeDir[dir], ind);
1682 }
1683
1684 void set_xdoorstate(int32_t screen,uint dir, uint ind)
1685 {
1686 int mi = mapind(cur_map, screen);
1687 set_xdoorstate_mi(mi, dir, ind);
1688 }
1689
1690 57 int32_t WARPCODE(int32_t dmap,int32_t screen,int32_t dw)
1691 // returns: -1 = not a warp screen
1692 // 0+ = warp screen code ( high byte=dmap, low byte=scr )
1693 {
1694 57 const mapscr *scr = get_canonical_scr(DMaps[dmap].map, screen);
1695
1696
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(scr->room!=rWARP)
1697 return -1;
1698
1699 57 int32_t ring=scr->catchall;
1700 57 int32_t size=QMisc.warp[ring].size;
1701
1702
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if(size==0)
1703 return -2;
1704
1705 57 int32_t index=-1;
1706
1707
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 57 times.
346 for(int32_t i=0; i<size; i++)
1708
6/6
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 173 times.
✓ Branch 5 taken 57 times.
289 if(dmap==QMisc.warp[ring].dmap[i] && screen==
1709 346 (QMisc.warp[ring].scr[i] + DMaps[dmap].xoff))
1710 57 index=i;
1711
1712
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(index==-1)
1713 return -3;
1714
1715 57 index = (index+dw)%size;
1716 57 return (QMisc.warp[ring].dmap[index] << 8) + QMisc.warp[ring].scr[index];
1717 57 }
1718
1719 14767531 void update_combo_cycling()
1720 {
1721 14767531 auto& combo_cache = combo_caches::can_cycle;
1722
1723 static int32_t newdata[176];
1724 static int32_t newcset[176];
1725 static bool initialized=false;
1726
1727 // Just a simple bit of optimization
1728
2/2
✓ Branch 0 taken 14767231 times.
✓ Branch 1 taken 300 times.
14767531 if(!initialized)
1729 {
1730
2/2
✓ Branch 0 taken 52800 times.
✓ Branch 1 taken 300 times.
53100 for(int32_t i=0; i<176; i++)
1731 {
1732 52800 newdata[i]=-1;
1733 52800 newcset[i]=-1;
1734 52800 }
1735
1736 300 initialized=true;
1737 300 }
1738
1739 14767531 std::set<uint16_t> restartanim;
1740
1741
1/2
✓ Branch 0 taken 14767531 times.
✗ Branch 1 not taken.
29924430 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
1742 15156899 int screen = scr->screen;
1743 int32_t x;
1744
1745
2/2
✓ Branch 0 taken 2667614224 times.
✓ Branch 1 taken 15156899 times.
2682771123 for(int32_t i=0; i<176; i++)
1746 {
1747 2667614224 x=scr->data[i];
1748 2667614224 auto& mini_cmb = combo_cache.minis[x];
1749
2/2
✓ Branch 0 taken 3273852 times.
✓ Branch 1 taken 2664340372 times.
2667614224 if (!mini_cmb.can_cycle)
1750 2664340372 continue;
1751
1752 3273852 newcombo const& cmb = combobuf[x];
1753
1754 //time to restart
1755
4/4
✓ Branch 0 taken 902678 times.
✓ Branch 1 taken 2371174 times.
✓ Branch 2 taken 474422 times.
✓ Branch 3 taken 428256 times.
3273852 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1756 {
1757 428256 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1758
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428256 times.
428256 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1759 428256 newdata[i] = c;
1760
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 428240 times.
428256 if(!(cmb.animflags & AF_CYCLENOCSET))
1761
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428240 times.
428240 newcset[i] = cycle_under ? scr->undercset : cmb.nextcset;
1762
1763
2/2
✓ Branch 0 taken 427212 times.
✓ Branch 1 taken 1044 times.
428256 if(combobuf[c].animflags & AF_CYCLE)
1764 {
1765 1044 restartanim.insert(c);
1766 1044 }
1767 428256 }
1768 3273852 }
1769
1770 15156899 int rpos_base = (int)POS_TO_RPOS(0, region_scr_x, region_scr_y);
1771
2/2
✓ Branch 0 taken 2667614224 times.
✓ Branch 1 taken 15156899 times.
2682771123 for(int32_t i=0; i<176; i++)
1772 {
1773
2/2
✓ Branch 0 taken 428256 times.
✓ Branch 1 taken 2667185968 times.
2667614224 if(newdata[i]==-1)
1774 2667185968 continue;
1775
1776 428256 rpos_t rpos = (rpos_t)(rpos_base + i);
1777 428256 rpos_handle_t rpos_handle = {scr, screen, 0, rpos, i};
1778 428256 screen_combo_modify_preroutine(rpos_handle);
1779 428256 scr->data[i]=newdata[i];
1780
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 428240 times.
428256 if(newcset[i]>-1)
1781 428240 scr->cset[i]=newcset[i];
1782 428256 screen_combo_modify_postroutine(rpos_handle);
1783
1784 428256 newdata[i]=-1;
1785 428256 newcset[i]=-1;
1786 428256 }
1787
1788 15156899 word c = scr->numFFC();
1789
2/2
✓ Branch 0 taken 15156899 times.
✓ Branch 1 taken 453626357 times.
468783256 for(word i=0; i<c; i++)
1790 {
1791 453626357 ffcdata& ffc = scr->ffcs[i];
1792 453626357 auto& mini_cmb = combo_cache.minis[ffc.data];
1793
2/2
✓ Branch 0 taken 4173 times.
✓ Branch 1 taken 453622184 times.
453626357 if (!mini_cmb.can_cycle)
1794 453622184 continue;
1795
1796 4173 newcombo const& cmb = combobuf[ffc.data];
1797
1798 //time to restart
1799
4/4
✓ Branch 0 taken 611 times.
✓ Branch 1 taken 3562 times.
✓ Branch 2 taken 503 times.
✓ Branch 3 taken 108 times.
4173 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1800 {
1801 108 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1802
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1803 108 zc_ffc_set(ffc, c);
1804
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if(!(cmb.animflags & AF_CYCLENOCSET))
1805
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 ffc.cset = cycle_under ? scr->undercset : cmb.nextcset;
1806
1807
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 60 times.
108 if(combobuf[ffc.data].animflags & AF_CYCLE)
1808 {
1809 60 restartanim.insert(ffc.data);
1810 60 }
1811 108 }
1812 4173 }
1813
1814
2/2
✓ Branch 0 taken 8417968 times.
✓ Branch 1 taken 6738931 times.
15156899 if(get_qr(qr_CMBCYCLELAYERS))
1815 {
1816
2/2
✓ Branch 0 taken 40433586 times.
✓ Branch 1 taken 6738931 times.
47172517 for(int32_t j=1; j<=6; j++)
1817 {
1818 40433586 mapscr* layer_scr = get_scr_layer_valid(screen, j);
1819
2/2
✓ Branch 0 taken 10859573 times.
✓ Branch 1 taken 29574013 times.
40433586 if (!layer_scr)
1820 29574013 continue;
1821
1822
2/2
✓ Branch 0 taken 1911284848 times.
✓ Branch 1 taken 10859573 times.
1922144421 for(int32_t i=0; i<176; i++)
1823 {
1824 1911284848 x=layer_scr->data[i];
1825 1911284848 auto& mini_cmb = combo_cache.minis[x];
1826
2/2
✓ Branch 0 taken 2228558 times.
✓ Branch 1 taken 1909056290 times.
1911284848 if (!mini_cmb.can_cycle)
1827 1909056290 continue;
1828
1829 2228558 newcombo const& cmb = combobuf[x];
1830
1831 //time to restart
1832
4/4
✓ Branch 0 taken 48215 times.
✓ Branch 1 taken 2180343 times.
✓ Branch 2 taken 37350 times.
✓ Branch 3 taken 10865 times.
2228558 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1833 {
1834 10865 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1835
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10865 times.
10865 auto c = cycle_under ? layer_scr->undercombo : cmb.nextcombo;
1836 10865 newdata[i] = c;
1837
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10864 times.
10865 if(!(cmb.animflags & AF_CYCLENOCSET))
1838
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10864 times.
10864 newcset[i] = cycle_under ? layer_scr->undercset : cmb.nextcset;
1839 1 else newcset[i] = layer_scr->cset[i];
1840
1841
2/2
✓ Branch 0 taken 890 times.
✓ Branch 1 taken 9975 times.
10865 if(combobuf[c].animflags & AF_CYCLE)
1842 {
1843 9975 restartanim.insert(c);
1844 9975 }
1845 10865 }
1846 2228558 }
1847
1848
2/2
✓ Branch 0 taken 1911284848 times.
✓ Branch 1 taken 10859573 times.
1922144421 for (int32_t i=0; i<176; i++)
1849 {
1850
2/2
✓ Branch 0 taken 1911273983 times.
✓ Branch 1 taken 10865 times.
1911284848 if(newdata[i]!=-1)
1851 {
1852 10865 layer_scr->data[i]=newdata[i];
1853
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10865 times.
10865 if(newcset[i]>-1)
1854 10865 layer_scr->cset[i]=newcset[i];
1855 10865 newdata[i]=-1;
1856 10865 newcset[i]=-1;
1857 10865 }
1858 1911284848 }
1859 10859573 }
1860 6738931 }
1861 15156899 });
1862
1863
2/2
✓ Branch 0 taken 14767531 times.
✓ Branch 1 taken 2657 times.
14770188 for (auto i : restartanim)
1864 {
1865 2657 combobuf[i].tile = combobuf[i].o_tile;
1866 2657 combobuf[i].cur_frame=0;
1867 2657 combobuf[i].aclk = 0;
1868
1/2
✓ Branch 0 taken 2657 times.
✗ Branch 1 not taken.
2657 combo_caches::drawing.refresh(i);
1869 }
1870 14767531 }
1871
1872 1204867082 bool iswater_type(int32_t type)
1873 {
1874 // return type==cOLD_WATER || type==cSWIMWARP || type==cDIVEWARP || type==cDIVEWARPB || type==cDIVEWARPC || type==cDIVEWARPD || type==cSWIMWARPB || type==cSWIMWARPC || type==cSWIMWARPD;
1875 1204867082 return (combo_class_buf[type].water!=0);
1876 }
1877
1878 bool iswater(int32_t combo)
1879 {
1880 return iswater_type(combobuf[combo].type) && !DRIEDLAKE;
1881 }
1882 1135408 int32_t iswaterexzq(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck)
1883 {
1884 1135408 return iswaterex(combo, map, screen, layer, x, y, secrets, fullcheck, LayerCheck);
1885 }
1886
1887 // (x, y) are world coordinates
1888 58608379 int32_t iswaterex_z3(int32_t combo, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero)
1889 {
1890
8/8
✓ Branch 0 taken 58562240 times.
✓ Branch 1 taken 46139 times.
✓ Branch 2 taken 58521923 times.
✓ Branch 3 taken 40317 times.
✓ Branch 4 taken 58455191 times.
✓ Branch 5 taken 66732 times.
✓ Branch 6 taken 59553 times.
✓ Branch 7 taken 58395638 times.
58608379 if (x<0 || x>=world_w || y<0 || y>=world_h)
1891 212741 return false;
1892
1893 58395638 return iswaterex(combo, cur_map, cur_screen, layer, x, y, secrets, fullcheck, LayerCheck, ShallowCheck, hero);
1894 58608379 }
1895
1896 96647549 int32_t iswaterex(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero)
1897 {
1898 DCHECK_LAYER_NEG1_INDEX(layer);
1899 //Honestly, fullcheck is kinda useless... I made this function back when I thought it was checking the entire combo and not just a glorified x/y value.
1900 //Fullcheck makes no sense to ever be on, but hey I guess it's here in case you ever need it...
1901
1902 //Oh hey, Zoras might actually need it. Nevermind, this had a use!
1903
2/2
✓ Branch 0 taken 56812878 times.
✓ Branch 1 taken 39834671 times.
96647549 if (get_qr(qr_SMARTER_WATER))
1904 {
1905
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 56812878 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
56812878 if (DRIEDLAKE) return 0;
1906
5/6
✓ Branch 0 taken 19424390 times.
✓ Branch 1 taken 37388488 times.
✓ Branch 2 taken 6518553 times.
✓ Branch 3 taken 12905837 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6518553 times.
56812878 if (LayerCheck && (get_qr(qr_WATER_ON_LAYER_1) || get_qr(qr_WATER_ON_LAYER_2))) //LayerCheck is a bit dumber, but it lets me add this QR without having to replace all calls, again.
1907 {
1908
2/2
✓ Branch 0 taken 37370967 times.
✓ Branch 1 taken 12232565 times.
49603532 for (int32_t m = layer; m <= 1; m++)
1909 {
1910
5/6
✓ Branch 0 taken 24465130 times.
✓ Branch 1 taken 12905837 times.
✓ Branch 2 taken 12232565 times.
✓ Branch 3 taken 12232565 times.
✓ Branch 4 taken 12232565 times.
✗ Branch 5 not taken.
49603532 if (m < 0 || m == 0 && get_qr(qr_WATER_ON_LAYER_1)
1911
1/2
✓ Branch 0 taken 12232565 times.
✗ Branch 1 not taken.
24465130 || m == 1 && get_qr(qr_WATER_ON_LAYER_2))
1912 {
1913 37370967 int32_t checkwater = iswaterex(combo, map, screen, m, x, y, secrets, fullcheck, false, ShallowCheck);
1914
2/2
✓ Branch 0 taken 36697695 times.
✓ Branch 1 taken 673272 times.
37370967 if (checkwater > 0)
1915 {
1916 673272 return checkwater;
1917 }
1918 36697695 }
1919 36697695 }
1920 12232565 return 0;
1921 }
1922 else
1923 {
1924
2/2
✓ Branch 0 taken 43921714 times.
✓ Branch 1 taken 41761943 times.
85683657 for(int32_t i=(fullcheck?3:0); i>=0; i--)
1925 {
1926 43921714 int32_t tx2=((i&2)<<2)+x;
1927 43921714 int32_t ty2=((i&1)<<3)+y;
1928 43921714 int32_t b = i; //Originally b was not needed and I read off i, but then I added the boolean for fullcheck.
1929 //In which case it's just easier to change b if fullcheck is false instead of changing i and potentially screwing up the for loop.
1930
2/2
✓ Branch 0 taken 21673 times.
✓ Branch 1 taken 43900041 times.
43921714 if (!fullcheck)
1931 {
1932 43900041 tx2 = x;
1933 43900041 ty2 = y;
1934
2/2
✓ Branch 0 taken 24646832 times.
✓ Branch 1 taken 19253209 times.
43900041 if(tx2&8) b+=2;
1935
2/2
✓ Branch 0 taken 20345121 times.
✓ Branch 1 taken 23554920 times.
43900041 if(ty2&8) b+=1;
1936 43900041 }
1937
2/2
✓ Branch 0 taken 93971005 times.
✓ Branch 1 taken 43106467 times.
137077472 for (int32_t m = layer; m <= 1; m++)
1938 {
1939 93971005 newcombo const& cmb = combobuf[MAPCOMBO3(map, screen, m,tx2,ty2, true)];
1940
2/2
✓ Branch 0 taken 17735679 times.
✓ Branch 1 taken 76235326 times.
93971005 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1941 {
1942
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17735679 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17735679 if (cmb.type == cBRIDGE && !(cmb.walk&(1<<b)))
1943 {
1944 return 0;
1945 }
1946 17735679 }
1947 else
1948 {
1949
4/4
✓ Branch 0 taken 159084 times.
✓ Branch 1 taken 76076242 times.
✓ Branch 2 taken 51152 times.
✓ Branch 3 taken 107932 times.
76235326 if (cmb.type == cBRIDGE && (cmb.walk&(0x10<<b)))
1950 {
1951 107932 return 0;
1952 }
1953 }
1954
2/2
✓ Branch 0 taken 17735679 times.
✓ Branch 1 taken 76127394 times.
93863073 if (get_qr(qr_NO_SOLID_SWIM))
1955 {
1956
8/14
✓ Branch 0 taken 51152 times.
✓ Branch 1 taken 76076242 times.
✓ Branch 2 taken 51152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 707315 times.
✓ Branch 5 taken 75368927 times.
✓ Branch 6 taken 3461 times.
✓ Branch 7 taken 703854 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3461 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
76127394 if ((cmb.type != cBRIDGE || (!get_qr(qr_OLD_BRIDGE_COMBOS) && !(cmb.walk&(0x10<<b)))) && (cmb.walk&(1<<b)) && !((cmb.usrflags&cflag4) && cmb.type == cWATER && (cmb.walk&(0x10<<b)) && ShallowCheck))
1957 {
1958 707315 return 0;
1959 }
1960 75420079 }
1961
3/6
✓ Branch 0 taken 320268 times.
✓ Branch 1 taken 92835490 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 320268 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
93155758 if (iswater_type(cmb.type) && (cmb.walk&(1<<b)) && ((cmb.usrflags&cflag3) || (cmb.usrflags&cflag4)
1962 || (hero && current_item(itype_flippers) < cmb.attribytes[0])
1963 || (hero && ((cmb.usrflags&cflag1) && !(itemsbuf[current_item_id(itype_flippers)].flags & item_flag3)))))
1964 {
1965 if (!(ShallowCheck && (cmb.walk&(1<<b)) && (cmb.usrflags&cflag4))) return 0;
1966 }
1967 93155758 }
1968
1969 130971580 auto found_ffc_not_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
1970
2/2
✓ Branch 0 taken 87337251 times.
✓ Branch 1 taken 527862 times.
87865113 if (ffcIsAt(ffc_handle, tx2, ty2))
1971 {
1972 527862 auto ty = ffc_handle.ctype();
1973
4/6
✓ Branch 0 taken 527862 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144225 times.
✓ Branch 3 taken 383637 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 144225 times.
527862 if(!combo_class_buf[ty].water && !(ShallowCheck && ty == cSHALLOWWATER))
1974 527862 return true;
1975 }
1976
1977 87337251 return false;
1978 87865113 });
1979
2/2
✓ Branch 0 taken 42578605 times.
✓ Branch 1 taken 527862 times.
43106467 if (found_ffc_not_water) return 0;
1980
1981
2/2
✓ Branch 0 taken 14673 times.
✓ Branch 1 taken 42563932 times.
42578605 if(!i)
1982 {
1983 127577271 auto found_ffc_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
1984
1/2
✓ Branch 0 taken 85013339 times.
✗ Branch 1 not taken.
85013339 if (ffcIsAt(ffc_handle, tx2, ty2))
1985 {
1986 auto ty = ffc_handle.ctype();
1987 if(combo_class_buf[ty].water || (ShallowCheck && ty == cSHALLOWWATER))
1988 return true;
1989 }
1990
1991 85013339 return false;
1992 85013339 });
1993
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42563932 times.
42563932 if (found_ffc_water) return found_ffc_water->data();
1994 42563932 }
1995
1996 42578605 int32_t checkcombo = MAPCOMBO3(map, screen, layer, tx2, ty2, secrets);
1997
2/2
✓ Branch 0 taken 42534111 times.
✓ Branch 1 taken 44494 times.
42578605 if (!(combobuf[checkcombo].walk&(1<<(b+4)))) return 0;
1998
7/12
✓ Branch 0 taken 42253573 times.
✓ Branch 1 taken 280538 times.
✓ Branch 2 taken 10721401 times.
✓ Branch 3 taken 31532172 times.
✓ Branch 4 taken 10243217 times.
✓ Branch 5 taken 478184 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 10243217 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
42534111 if (iswater_type(combobuf[checkcombo].type)||(ShallowCheck && (combobuf[checkcombo].type == cSHALLOWWATER || (iswater_type(combobuf[checkcombo].type) && (combobuf[checkcombo].walk&(1<<b)) && (combobuf[checkcombo].usrflags&cflag4)))))
1999 {
2000
2/2
✓ Branch 0 taken 1227 times.
✓ Branch 1 taken 757495 times.
758722 if (i == 0) return checkcombo;
2001 1227 }
2002 41776616 }
2003 41761943 return 0;
2004 }
2005 }
2006 else
2007 {
2008 39834671 int32_t b = 0;
2009
2/2
✓ Branch 0 taken 20621822 times.
✓ Branch 1 taken 19212849 times.
39834671 if(x&8) b+=2;
2010
2/2
✓ Branch 0 taken 15442035 times.
✓ Branch 1 taken 24392636 times.
39834671 if(y&8) b+=1;
2011
1/2
✓ Branch 0 taken 39834671 times.
✗ Branch 1 not taken.
39834671 if (get_qr(qr_NO_SOLID_SWIM))
2012 {
2013 if (combobuf[combo].walk&(1<<b))
2014 {
2015 return 0;
2016 }
2017 }
2018
1/2
✓ Branch 0 taken 39834671 times.
✗ Branch 1 not taken.
39834671 if (!(combobuf[combo].walk&(1<<(b+4)))) return 0;
2019
8/8
✓ Branch 0 taken 38150503 times.
✓ Branch 1 taken 1684168 times.
✓ Branch 2 taken 167945 times.
✓ Branch 3 taken 37982558 times.
✓ Branch 4 taken 2129 times.
✓ Branch 5 taken 1782308 times.
✓ Branch 6 taken 163774 times.
✓ Branch 7 taken 161691 times.
39834671 return (((iswater_type(combobuf[combo].type) || (ShallowCheck && combobuf[combo].type == cSHALLOWWATER)) && !DRIEDLAKE)?combo:0);//These used to return booleans; returning the combo id of the water combo it caught is essential for Emily's proposed water changes.
2020 }
2021 96903209 }
2022
2023 326 bool isdamage_type(int32_t type)
2024 {
2025
1/2
✓ Branch 0 taken 326 times.
✗ Branch 1 not taken.
326 switch(type)
2026 {
2027 case cDAMAGE1: case cDAMAGE2: case cDAMAGE3: case cDAMAGE4:
2028 case cDAMAGE5: case cDAMAGE6: case cDAMAGE7:
2029 return true;
2030 }
2031 326 return false;
2032 326 }
2033
2034 2568913724 bool ispitfall_type(int32_t type)
2035 {
2036 2568913724 return combo_class_buf[type].pit != 0;
2037 }
2038
2039 2568913724 bool ispitfall(int32_t combo)
2040 {
2041 2568913724 return ispitfall_type(combobuf[combo].type);
2042 }
2043
2044 277745561 bool ispitfall(int32_t x, int32_t y)
2045 {
2046
2/2
✓ Branch 0 taken 1454897 times.
✓ Branch 1 taken 276290664 times.
277745561 if(int32_t c = MAPFFCOMBO(x,y))
2047 {
2048 1454897 return ispitfall(c) ? true : false;
2049 }
2050 276290664 int32_t c = MAPCOMBOL(2,x,y);
2051
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 276290664 times.
276290664 if(ispitfall(c)) return true;
2052
2/2
✓ Branch 0 taken 263213577 times.
✓ Branch 1 taken 13077087 times.
276290664 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2053 {
2054
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 263213577 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
263213577 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return false;
2055 263213577 }
2056 else
2057 {
2058
3/4
✓ Branch 0 taken 340 times.
✓ Branch 1 taken 13076747 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 340 times.
13077087 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return false;
2059 }
2060 276290324 c = MAPCOMBOL(1,x,y);
2061
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 276290300 times.
276290324 if(ispitfall(c)) return true;
2062
2063
2/2
✓ Branch 0 taken 263213577 times.
✓ Branch 1 taken 13076723 times.
276290300 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2064 {
2065
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 263213577 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
263213577 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return false;
2066 263213577 }
2067 else
2068 {
2069
4/4
✓ Branch 0 taken 13072 times.
✓ Branch 1 taken 13063651 times.
✓ Branch 2 taken 8777 times.
✓ Branch 3 taken 4295 times.
13076723 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return false;
2070 }
2071 276281523 c = MAPCOMBO(x,y);
2072
2/2
✓ Branch 0 taken 70742 times.
✓ Branch 1 taken 276210781 times.
276281523 if(ispitfall(c)) return true;
2073 276210781 return false;
2074 277745561 }
2075
2076 585756029 int32_t getpitfall(int32_t x, int32_t y) //Return the highest-layer active pit combo at the given position
2077 {
2078
2/2
✓ Branch 0 taken 9280750 times.
✓ Branch 1 taken 576475279 times.
585756029 if(int32_t c = MAPFFCOMBO(x,y))
2079 {
2080
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9280750 times.
9280750 return ispitfall(c) ? c : 0;
2081 }
2082 576475279 int32_t c = MAPCOMBOL(2,x,y);
2083
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 576475279 times.
576475279 if(ispitfall(c)) return c;
2084
2085
2/2
✓ Branch 0 taken 533324286 times.
✓ Branch 1 taken 43150993 times.
576475279 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2086 {
2087
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 533324286 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
533324286 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return 0;
2088 533324286 }
2089 else
2090 {
2091
3/4
✓ Branch 0 taken 3132 times.
✓ Branch 1 taken 43147861 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3132 times.
43150993 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return 0;
2092 }
2093 576472147 c = MAPCOMBOL(1,x,y);
2094
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 576471869 times.
576472147 if(ispitfall(c)) return c;
2095
2096
2/2
✓ Branch 0 taken 533324286 times.
✓ Branch 1 taken 43147583 times.
576471869 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2097 {
2098
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 533324286 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
533324286 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return 0;
2099 533324286 }
2100 else
2101 {
2102
4/4
✓ Branch 0 taken 144357 times.
✓ Branch 1 taken 43003226 times.
✓ Branch 2 taken 103729 times.
✓ Branch 3 taken 40628 times.
43147583 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return 0;
2103 }
2104 576368140 c = MAPCOMBO(x,y);
2105
2/2
✓ Branch 0 taken 175967 times.
✓ Branch 1 taken 576192173 times.
576368140 if(ispitfall(c)) return c;
2106 576192173 return 0;
2107 585756029 }
2108 5324955 bool check_icy(newcombo const& cmb, int type)
2109 {
2110
1/2
✓ Branch 0 taken 5324955 times.
✗ Branch 1 not taken.
5324955 if(cmb.type != cICY)
2111 5324955 return false;
2112 switch(type)
2113 {
2114 case ICY_BLOCK:
2115 return cmb.usrflags&cflag1;
2116 case ICY_PLAYER:
2117 return cmb.usrflags&cflag2;
2118 }
2119 return false;
2120 5324955 }
2121 1775532 int get_icy(int x, int y, int type)
2122 {
2123 1775532 int32_t c = MAPCOMBOL(2,x,y);
2124
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1775532 times.
1775532 if(check_icy(combobuf[c], type)) return c;
2125
2126 1775532 int screen = get_screen_for_world_xy(x, y);
2127
2128 1775532 mapscr* scr = get_scr_layer_valid(screen, 2);
2129
2/2
✓ Branch 0 taken 430769 times.
✓ Branch 1 taken 1344763 times.
1775532 if (scr)
2130 {
2131
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 1344247 times.
1344763 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2132 {
2133
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 516 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
516 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2134 516 }
2135 else
2136 {
2137
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1344247 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1344247 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2138 }
2139 1344763 }
2140 1775532 c = MAPCOMBOL(1,x,y);
2141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1775532 times.
1775532 if(check_icy(combobuf[c], type)) return c;
2142
2143 1775532 scr = get_scr_layer_valid(screen, 1);
2144
2/2
✓ Branch 0 taken 73612 times.
✓ Branch 1 taken 1701920 times.
1775532 if (scr)
2145 {
2146
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 1699986 times.
1701920 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2147 {
2148
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1934 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1934 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2149 1934 }
2150 else
2151 {
2152
3/4
✓ Branch 0 taken 1641 times.
✓ Branch 1 taken 1698345 times.
✓ Branch 2 taken 1641 times.
✗ Branch 3 not taken.
1699986 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2153 }
2154 1700279 }
2155 1773891 c = MAPCOMBO(x,y);
2156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1773891 times.
1773891 if(check_icy(combobuf[c], type)) return c;
2157 1773891 return 0;
2158 1775532 }
2159
2160 13027448 static bool checkSV(int32_t x, int32_t y, int32_t flag)
2161 {
2162
8/8
✓ Branch 0 taken 13020650 times.
✓ Branch 1 taken 6798 times.
✓ Branch 2 taken 13011784 times.
✓ Branch 3 taken 8866 times.
✓ Branch 4 taken 13000152 times.
✓ Branch 5 taken 11632 times.
✓ Branch 6 taken 428460 times.
✓ Branch 7 taken 12571692 times.
13027448 if(x<0 || x>=world_w || y<0 || y>=world_h)
2163 455756 return false;
2164
2165 12571692 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
2166
2/4
✓ Branch 0 taken 12571692 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12571692 times.
12571692 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2167 return true;
2168
2169 12571692 change_rpos_handle_layer(rpos_handle, 1);
2170
2/2
✓ Branch 0 taken 7563722 times.
✓ Branch 1 taken 5007970 times.
12571692 if (rpos_handle.scr->is_valid())
2171
2/4
✓ Branch 0 taken 5007970 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5007970 times.
5007970 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2172 return true;
2173
2174 12571692 change_rpos_handle_layer(rpos_handle, 2);
2175
2/2
✓ Branch 0 taken 10875016 times.
✓ Branch 1 taken 1696676 times.
12571692 if (rpos_handle.scr->is_valid())
2176
2/4
✓ Branch 0 taken 1696676 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1696676 times.
1696676 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2177 return true;
2178
2179 12571692 return false;
2180 13027448 }
2181
2182 6576630 bool isSVLadder(int32_t x, int32_t y)
2183 {
2184 6576630 return checkSV(x, y, mfSIDEVIEWLADDER);
2185 }
2186
2187 6450818 bool isSVPlatform(int32_t x, int32_t y)
2188 {
2189 6450818 return checkSV(x, y, mfSIDEVIEWPLATFORM);
2190 }
2191
2192 6450818 bool checkSVLadderPlatform(int32_t x, int32_t y)
2193 {
2194
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6450818 times.
✓ Branch 2 taken 6450818 times.
✗ Branch 3 not taken.
6450818 return isSVPlatform(x,y) || (isSVLadder(x,y) && !isSVLadder(x,y-16));
2195 }
2196
2197 1637 bool isstepable(int32_t combo) //can use ladder on it
2198 {
2199
2/2
✓ Branch 0 taken 1631 times.
✓ Branch 1 taken 6 times.
1637 if(combo_class_buf[combobuf[combo].type].ladder_pass) return true;
2200
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(combo_class_buf[combobuf[combo].type].pit)
2201 {
2202 if(combobuf[combo].usrflags&cflag4)
2203 {
2204 int32_t ldrid = current_item_id(itype_ladder);
2205 return (ldrid > -1 && itemsbuf[ldrid].flags & item_flag1);
2206 }
2207 }
2208 6 return false;
2209 1637 }
2210
2211 32780 bool isHSGrabbable(newcombo const& cmb)
2212 {
2213
2/2
✓ Branch 0 taken 373 times.
✓ Branch 1 taken 32407 times.
32780 if(cmb.type == cHSGRAB) return true;
2214 32407 return cmb.genflags & cflag1;
2215 32780 }
2216
2217 954 bool isSwitchHookable(newcombo const& cmb)
2218 {
2219
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 822 times.
954 if(cmb.type == cSWITCHHOOK) return true;
2220 822 return cmb.genflags & cflag2;
2221 954 }
2222
2223 61401 bool check_hshot(int32_t layer, int32_t x, int32_t y, bool switchhook, rpos_t *out_rpos, ffcdata **out_ffc)
2224 {
2225 61401 rpos_t cpos = rpos_t::None;
2226
2/2
✓ Branch 0 taken 64592 times.
✓ Branch 1 taken 125993 times.
61401 if(out_rpos)
2227 {
2228 125993 int32_t id = MAPCOMBO2(layer-1,x,y);
2229
2/2
✓ Branch 0 taken 28634 times.
✓ Branch 1 taken 97359 times.
125993 if(id > 0)
2230 {
2231 97359 newcombo const& cmb = combobuf[id];
2232
4/4
✓ Branch 0 taken 32738 times.
✓ Branch 1 taken 64621 times.
✓ Branch 2 taken 32296 times.
✓ Branch 3 taken 32325 times.
97359 cpos = (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb)) ? COMBOPOS_REGION(x,y) : rpos_t::None;
2233 32767 }
2234 61401 }
2235
2236 125993 ffcdata* ffc = nullptr;
2237
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 24996 times.
✓ Branch 3 taken 3393 times.
125993 if (out_ffc && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2238 {
2239 10359 for_some_ffcs([&](const ffc_handle_t& ffc_handle) {
2240
2/2
✓ Branch 0 taken 6853 times.
✓ Branch 1 taken 113 times.
6966 if (ffcIsAt(ffc_handle, x, y))
2241 {
2242 113 auto& cmb = ffc_handle.combo();
2243
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 71 times.
✓ Branch 2 taken 35 times.
✓ Branch 3 taken 36 times.
113 if (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb))
2244 {
2245 77 ffc = ffc_handle.ffc;
2246 77 return false;
2247 }
2248 36 }
2249 6889 return true;
2250 6896 });
2251 3393 }
2252
2253
4/4
✓ Branch 0 taken 61401 times.
✓ Branch 1 taken 64592 times.
✓ Branch 2 taken 442 times.
✓ Branch 3 taken 60959 times.
125993 if (out_rpos && cpos != rpos_t::None) *out_rpos = cpos;
2254
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 28382 times.
125993 if (out_ffc && ffc) *out_ffc = ffc;
2255
2/2
✓ Branch 0 taken 65034 times.
✓ Branch 1 taken 60959 times.
125993 return (cpos != rpos_t::None || ffc);
2256 }
2257
2258 5195 bool ishookshottable(int32_t bx, int32_t by)
2259 {
2260
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5195 times.
5195 if(!_walkflag(bx,by,1))
2261 return true;
2262
2263
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5187 times.
5195 if (collide_object(bx, by, 1, 1))
2264 8 return false;
2265
2266 5187 bool ret = true;
2267
2/2
✓ Branch 0 taken 15561 times.
✓ Branch 1 taken 1900 times.
17461 for(int32_t i=2; i>=0; i--)
2268 {
2269 15561 int32_t c = MAPCOMBO2(i-1,bx,by);
2270 15561 int32_t t = combobuf[c].type;
2271
2272
6/6
✓ Branch 0 taken 5187 times.
✓ Branch 1 taken 10374 times.
✓ Branch 2 taken 3853 times.
✓ Branch 3 taken 1334 times.
✓ Branch 4 taken 1900 times.
✓ Branch 5 taken 1953 times.
15561 if(i == 0 && (t == cHOOKSHOTONLY || t == cLADDERHOOKSHOT)) return true;
2273
2274
3/4
✓ Branch 0 taken 11321 times.
✓ Branch 1 taken 953 times.
✓ Branch 2 taken 953 times.
✗ Branch 3 not taken.
13227 bool dried = (iswater_type(t) && DRIEDLAKE);
2275
2276 12274 int32_t b=1;
2277
2278
2/2
✓ Branch 0 taken 6109 times.
✓ Branch 1 taken 6165 times.
12274 if(bx&8) b<<=2;
2279
2280
2/2
✓ Branch 0 taken 3841 times.
✓ Branch 1 taken 8433 times.
12274 if(by&8) b<<=1;
2281
2282
7/8
✓ Branch 0 taken 2094 times.
✓ Branch 1 taken 10180 times.
✓ Branch 2 taken 2094 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1115 times.
✓ Branch 5 taken 979 times.
✓ Branch 6 taken 75 times.
✓ Branch 7 taken 904 times.
12274 if(combobuf[c].walk&b && !dried && !(combo_class_buf[t].ladder_pass && t!=cLADDERONLY) && t!=cHOOKSHOTONLY)
2283 904 ret = false;
2284 12274 }
2285
2286 1900 return ret;
2287 5195 }
2288
2289 10105 bool reveal_hidden_stairs(mapscr *s, int32_t screen, bool redraw)
2290 {
2291
4/4
✓ Branch 0 taken 9526 times.
✓ Branch 1 taken 579 times.
✓ Branch 2 taken 9526 times.
✓ Branch 3 taken 579 times.
10105 if((s->stairx || s->stairy) && s->secretcombo[sSTAIRS])
2292 {
2293 579 int pos = COMBOPOS(s->stairx,s->stairy);
2294 579 s->data[pos] = s->secretcombo[sSTAIRS];
2295 579 s->cset[pos] = s->secretcset[sSTAIRS];
2296 579 s->sflag[pos] = s->secretflag[sSTAIRS];
2297
2298
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 323 times.
579 if (redraw)
2299 {
2300 768 auto [x, y] = translate_screen_coordinates_to_world(screen, s->stairx, s->stairy);
2301 768 putcombo(scrollbuf,x,y,s->data[pos],s->cset[pos]);
2302 256 }
2303
2304 579 return true;
2305 }
2306
2307 9526 return false;
2308 10105 }
2309
2310 15796 screen_handles_t create_screen_handles_one(mapscr* base_scr)
2311 {
2312 DCHECK(base_scr->is_valid());
2313
2314 15796 screen_handles_t screen_handles{};
2315 15796 screen_handles[0] = {base_scr, base_scr, base_scr->screen, 0};
2316 15796 return screen_handles;
2317 }
2318
2319 56472360 screen_handles_t create_screen_handles(mapscr* base_scr)
2320 {
2321 DCHECK(get_scr(base_scr->screen) == base_scr);
2322 DCHECK(base_scr->is_valid());
2323
2324 56472360 int screen = base_scr->screen;
2325 screen_handles_t screen_handles;
2326 56472360 screen_handles[0] = {base_scr, base_scr, screen, 0};
2327
2/2
✓ Branch 0 taken 338834160 times.
✓ Branch 1 taken 56472360 times.
395306520 for (int i = 1; i <= 6; i++)
2328 338834160 screen_handles[i] = {base_scr, get_scr_layer_valid(screen, i), screen, i};
2329 56472360 return screen_handles;
2330 }
2331
2332 106202 bool remove_screenstatecombos2(const screen_handles_t& screen_handles, bool do_layers, int32_t what1, int32_t what2)
2333 {
2334 106202 mapscr* scr = screen_handles[0].scr;
2335 106202 bool didit=false;
2336
2337
2/2
✓ Branch 0 taken 106202 times.
✓ Branch 1 taken 18691552 times.
18797754 for(int32_t i=0; i<176; i++)
2338 {
2339 18691552 newcombo const& cmb = combobuf[scr->data[i]];
2340
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 18691226 times.
18691552 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2341
4/4
✓ Branch 0 taken 18689693 times.
✓ Branch 1 taken 1533 times.
✓ Branch 2 taken 1102 times.
✓ Branch 3 taken 18688591 times.
18691226 if((cmb.type == what1) || (cmb.type== what2))
2342 {
2343 2635 scr->data[i]++;
2344 2635 didit=true;
2345 2635 }
2346 18691226 }
2347
2348
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 106110 times.
106202 if (do_layers)
2349 {
2350
2/2
✓ Branch 0 taken 636660 times.
✓ Branch 1 taken 106110 times.
742770 for(int32_t j=1; j<=6; j++)
2351 {
2352 636660 mapscr* layer_scr = screen_handles[j].scr;
2353
2/2
✓ Branch 0 taken 173044 times.
✓ Branch 1 taken 463616 times.
636660 if (!layer_scr) continue;
2354
2355
2/2
✓ Branch 0 taken 30455744 times.
✓ Branch 1 taken 173044 times.
30628788 for(int32_t i=0; i<176; i++)
2356 {
2357 30455744 newcombo const& cmb = combobuf[layer_scr->data[i]];
2358
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30455744 times.
30455744 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2359
4/4
✓ Branch 0 taken 30455661 times.
✓ Branch 1 taken 83 times.
✓ Branch 2 taken 265 times.
✓ Branch 3 taken 30455396 times.
30455744 if((cmb.type== what1) || (cmb.type== what2))
2360 {
2361 348 layer_scr->data[i]++;
2362 348 didit=true;
2363 348 }
2364 30455744 }
2365 173044 }
2366 106110 }
2367
2368 // 'do_layers' also means that this is called on an active temp screen, so update its ffcs.
2369
3/4
✓ Branch 0 taken 20406 times.
✓ Branch 1 taken 85796 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20406 times.
106202 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && do_layers)
2370 {
2371 20406 word c = scr->numFFC();
2372
2/2
✓ Branch 0 taken 73350 times.
✓ Branch 1 taken 20406 times.
93756 for(word i=0; i<c; i++)
2373 {
2374 73350 ffcdata* ffc = &scr->ffcs[i];
2375 73350 newcombo const& cmb = combobuf[ffc->data];
2376
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73350 times.
73350 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2377
2/4
✓ Branch 0 taken 73350 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 73350 times.
73350 if((cmb.type== what1) || (cmb.type== what2))
2378 {
2379 zc_ffc_modify(*ffc, 1);
2380 didit=true;
2381 }
2382 73350 }
2383 20406 }
2384
2385 106202 return didit;
2386 }
2387
2388 14 bool remove_xstatecombos(const screen_handles_t& screen_handles, byte xflag, bool triggers)
2389 {
2390 14 int screen = screen_handles[0].scr->screen;
2391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2392 14 return remove_xstatecombos_mi(screen_handles, mi, xflag, triggers);
2393 }
2394 471118798 bool remove_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, byte xflag, bool triggers)
2395 {
2396 471118798 bool didit=false;
2397
2/2
✓ Branch 0 taken 471094305 times.
✓ Branch 1 taken 24493 times.
471118798 if(!getxmapflag_mi(mi, 1<<xflag)) return false;
2398
2399 24493 mapscr* s = screen_handles[0].scr;
2400 24493 int screen = s->screen;
2401 24493 bool is_active_screen = is_in_current_region(s);
2402
2403 21171069 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2404
4/4
✓ Branch 0 taken 21134960 times.
✓ Branch 1 taken 11616 times.
✓ Branch 2 taken 21133233 times.
✓ Branch 3 taken 1727 times.
21146576 if(triggers && force_ex_trigger_any(rpos_handle, xflag))
2405 1727 didit = true;
2406
2/2
✓ Branch 0 taken 63627 times.
✓ Branch 1 taken 21081222 times.
21144849 else switch (rpos_handle.ctype())
2407 {
2408 case cLOCKBLOCK: case cLOCKBLOCK2:
2409 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2410 case cCHEST: case cCHEST2:
2411 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2412 case cBOSSCHEST: case cBOSSCHEST2:
2413 {
2414 63627 auto& cmb = rpos_handle.combo();
2415
2/2
✓ Branch 0 taken 62059 times.
✓ Branch 1 taken 1568 times.
63627 if(!(cmb.usrflags&cflag16)) return; //custom state instead of normal state
2416
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 62030 times.
62059 if(cmb.attribytes[5] == xflag)
2417 {
2418 29 rpos_handle.increment_data();
2419 29 didit=true;
2420 29 }
2421 62059 break;
2422 }
2423 }
2424 21146576 });
2425
2426
4/4
✓ Branch 0 taken 24452 times.
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 14832 times.
✓ Branch 3 taken 9620 times.
24493 if (is_active_screen && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2427 {
2428 14832 word c = s->numFFC();
2429 14832 int screen_index_offset = get_region_screen_offset(screen);
2430
2/2
✓ Branch 0 taken 36840 times.
✓ Branch 1 taken 14832 times.
51672 for (uint8_t i = 0; i < c; i++)
2431 {
2432 36840 auto ffc_handle = *s->getFFCHandle(i, screen_index_offset);
2433 36840 auto& cmb = ffc_handle.combo();
2434
3/4
✓ Branch 0 taken 36840 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36824 times.
✓ Branch 3 taken 16 times.
36840 if(triggers && force_ex_trigger_ffc_any(ffc_handle, xflag))
2435 16 didit = true;
2436
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36824 times.
36824 else switch(cmb.type)
2437 {
2438 case cLOCKBLOCK: case cLOCKBLOCK2:
2439 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2440 case cCHEST: case cCHEST2:
2441 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2442 case cBOSSCHEST: case cBOSSCHEST2:
2443 {
2444 if(!(cmb.usrflags&cflag16)) continue; //custom state instead of normal state
2445 if(cmb.attribytes[5] == xflag)
2446 {
2447 zc_ffc_modify(*ffc_handle.ffc, 1);
2448 didit=true;
2449 }
2450 break;
2451 }
2452 }
2453 36840 }
2454 14832 }
2455
2456 24493 return didit;
2457 471118798 }
2458
2459 14670499 void clear_xstatecombos(const screen_handles_t& screen_handles, bool triggers)
2460 {
2461 14670499 int screen = screen_handles[0].screen;
2462
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14282666 times.
14670499 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2463 14670499 clear_xstatecombos_mi(screen_handles, mi, triggers);
2464 14670499 }
2465
2466 14722462 void clear_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2467 {
2468
2/2
✓ Branch 0 taken 471118784 times.
✓ Branch 1 taken 14722462 times.
485841246 for (int q = 0; q < 32; ++q)
2469 {
2470 471118784 remove_xstatecombos_mi(screen_handles, mi, q, triggers);
2471 471118784 }
2472 14722462 }
2473
2474 471118784 bool remove_xdoors(const screen_handles_t& screen_handles, uint dir, uint ind, bool triggers)
2475 {
2476 471118784 int screen = screen_handles[0].screen;
2477
2/2
✓ Branch 0 taken 12412256 times.
✓ Branch 1 taken 458706528 times.
471118784 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2478 471118784 return remove_xdoors_mi(screen_handles, mi, dir, ind, triggers);
2479 }
2480 471118784 bool remove_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, uint dir, uint ind, bool triggers)
2481 {
2482 471118784 bool didit=false;
2483
1/2
✓ Branch 0 taken 471118784 times.
✗ Branch 1 not taken.
471118784 if (!getxdoor_mi(mi, dir, ind)) return false;
2484
2485 mapscr* scr = screen_handles[0].scr;
2486 int screen = scr->screen;
2487 bool is_active_screen = is_in_current_region(scr);
2488
2489 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2490 if (triggers && force_ex_door_trigger_any(rpos_handle, dir, ind))
2491 didit = true;
2492 else; //future door combo types?
2493 });
2494
2495 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && is_active_screen)
2496 {
2497 word c = scr->numFFC();
2498 int screen_index_offset = get_region_screen_offset(screen);
2499 for (uint8_t i = 0; i < c; i++)
2500 {
2501 auto ffc_handle = *scr->getFFCHandle(i, screen_index_offset);
2502 if (triggers && force_ex_door_trigger_ffc_any(ffc_handle, dir, ind))
2503 didit = true;
2504 else; //future door combo types?
2505 }
2506 }
2507
2508 return didit;
2509 471118784 }
2510
2511 14670499 void clear_xdoors(const screen_handles_t& screen_handles, bool triggers)
2512 {
2513 14670499 mapscr* scr = screen_handles[0].scr;
2514
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14282666 times.
14670499 int mi = mapind(cur_map, scr->screen >= 0x80 ? home_screen : scr->screen);
2515 14670499 clear_xdoors_mi(screen_handles, mi, triggers);
2516 14670499 }
2517
2518 14722462 void clear_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2519 {
2520
2/2
✓ Branch 0 taken 471118784 times.
✓ Branch 1 taken 14722462 times.
485841246 for (int q = 0; q < 32; ++q)
2521 {
2522 471118784 remove_xdoors(screen_handles, mi, q, triggers);
2523 471118784 }
2524 14722462 }
2525
2526 763 bool remove_lockblocks(const screen_handles_t& screen_handles)
2527 {
2528 763 return remove_screenstatecombos2(screen_handles, true, cLOCKBLOCK, cLOCKBLOCK2);
2529 }
2530
2531 98 bool remove_bosslockblocks(const screen_handles_t& screen_handles)
2532 {
2533 98 return remove_screenstatecombos2(screen_handles, true, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
2534 }
2535
2536 76553 bool remove_chests(const screen_handles_t& screen_handles)
2537 {
2538 76553 return remove_screenstatecombos2(screen_handles, true, cCHEST, cCHEST2);
2539 }
2540
2541 2484 bool remove_lockedchests(const screen_handles_t& screen_handles)
2542 {
2543 2484 return remove_screenstatecombos2(screen_handles, true, cLOCKEDCHEST, cLOCKEDCHEST2);
2544 }
2545
2546 26212 bool remove_bosschests(const screen_handles_t& screen_handles)
2547 {
2548 26212 return remove_screenstatecombos2(screen_handles, true, cBOSSCHEST, cBOSSCHEST2);
2549 }
2550
2551 1383999 void delete_fireball_shooter(const rpos_handle_t& rpos_handle)
2552 {
2553 1383999 int32_t ct=rpos_handle.ctype();
2554
2555
6/6
✓ Branch 0 taken 1383379 times.
✓ Branch 1 taken 620 times.
✓ Branch 2 taken 1383127 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 1383019 times.
✓ Branch 5 taken 108 times.
1383999 if(ct!=cL_STATUE && ct!=cR_STATUE && ct!=cC_STATUE)
2556 1383019 return;
2557
2558 2465 auto [cx, cy] = rpos_handle.xy();
2559
3/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 620 times.
✓ Branch 3 taken 108 times.
980 switch(ct)
2560 {
2561 case cL_STATUE:
2562 620 cx += 4;
2563 620 cy += 7;
2564 620 break;
2565
2566 case cR_STATUE:
2567 252 cx -= 8;
2568 252 cy -= 1;
2569 252 break;
2570
2571 case cC_STATUE:
2572 108 break;
2573 }
2574
2575
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 1485 times.
2465 for(int32_t j=0; j<guys.Count(); j++)
2576 {
2577 // Finds the smallest enemy ID
2578
9/10
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 1086 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 53 times.
✓ Branch 8 taken 346 times.
✗ Branch 9 not taken.
2970 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy)&&(guysbuf[(guys.spr(j)->id)&0xFFF].flags & guy_fire))
2579 {
2580 346 guys.del(j);
2581 346 }
2582 1485 }
2583 1383999 }
2584
2585 15 static int32_t findtrigger(int32_t screen)
2586 {
2587 15 int32_t checkflag=0;
2588 15 int32_t ret = 0;
2589
2590 mapscr* screens[7];
2591
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 15 times.
120 for (int32_t j = 0; j <= 6; j++)
2592 {
2593 105 screens[j] = get_scr_layer_valid(screen, j);
2594 105 }
2595
2596 15 bool sflag = false;
2597
2/2
✓ Branch 0 taken 2640 times.
✓ Branch 1 taken 15 times.
2655 for(word j=0; j<176; j++)
2598 {
2599
2/2
✓ Branch 0 taken 26752 times.
✓ Branch 1 taken 2640 times.
29392 for(int32_t layer = -1; layer < 6; ++layer)
2600 {
2601 26752 mapscr* scr = screens[layer+1];
2602
2/2
✓ Branch 0 taken 16544 times.
✓ Branch 1 taken 10208 times.
26752 if (!scr) continue;
2603
2604
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if(sflag)
2605 8272 checkflag = scr->sflag[j];
2606 else
2607 8272 checkflag = combobuf[scr->data[j]].flag;
2608 16544 sflag = !sflag;
2609
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if (sflag) --layer;
2610
2611
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 16534 times.
16544 switch(checkflag)
2612 {
2613 case mfANYFIRE:
2614 case mfSTRONGFIRE:
2615 case mfMAGICFIRE:
2616 case mfDIVINEFIRE:
2617 case mfARROW:
2618 case mfSARROW:
2619 case mfGARROW:
2620 case mfSBOMB:
2621 case mfBOMB:
2622 case mfBRANG:
2623 case mfMBRANG:
2624 case mfFBRANG:
2625 case mfWANDMAGIC:
2626 case mfREFMAGIC:
2627 case mfREFFIREBALL:
2628 case mfSWORD:
2629 case mfWSWORD:
2630 case mfMSWORD:
2631 case mfXSWORD:
2632 case mfSWORDBEAM:
2633 case mfWSWORDBEAM:
2634 case mfMSWORDBEAM:
2635 case mfXSWORDBEAM:
2636 case mfHOOKSHOT:
2637 case mfWAND:
2638 case mfHAMMER:
2639 case mfSTRIKE:
2640 10 ret += 1;
2641 10 break;
2642 }
2643 16544 }
2644 2640 }
2645
2646 15 return ret;
2647 }
2648
2649 11734 static void log_trigger_secret_reason(TriggerSource source)
2650 {
2651
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11295 times.
11734 if (source == TriggerSource::Singular)
2652 {
2653 439 Z_eventlog("Restricted Screen Secrets triggered\n");
2654 439 }
2655 else
2656 {
2657 11295 const char* source_str = "";
2658
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7178 times.
✓ Branch 3 taken 856 times.
✓ Branch 4 taken 2732 times.
✓ Branch 5 taken 475 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 49 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
11295 switch (source)
2659 {
2660 case TriggerSource::Singular: break;
2661 7178 case TriggerSource::Unspecified: source_str = "unspecified means"; break;
2662 856 case TriggerSource::EnemiesScreenFlag: source_str = "the 'Enemies->Secret' screen flag"; break;
2663 2732 case TriggerSource::SecretsScreenState: source_str = "the 'Secrets' screen state"; break;
2664 475 case TriggerSource::Script: source_str = "a script"; break;
2665 1 case TriggerSource::ItemsSecret: source_str = "Items->Secrets"; break;
2666 49 case TriggerSource::GenericCombo: source_str = "Generic Combo"; break;
2667 4 case TriggerSource::LightTrigger: source_str = "Light Triggers"; break;
2668 case TriggerSource::SCC: source_str = "SCC"; break;
2669 case TriggerSource::CheatTemp: source_str = "Cheat (Temp)"; break;
2670 case TriggerSource::CheatPerm: source_str = "Cheat (Perm)"; break;
2671 }
2672 11295 Z_eventlog("Screen Secrets triggered by %s\n", source_str);
2673 }
2674 11734 }
2675
2676 // single:
2677 // >-1 : the singular triggering combo
2678 // -1: triggered by some other cause
2679 11526 void trigger_secrets_for_screen(TriggerSource source, mapscr* scr, bool high16only, int32_t single)
2680 {
2681 11526 log_trigger_secret_reason(source);
2682
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11087 times.
11526 if (single < 0)
2683 11087 get_screen_state(scr->screen).triggered_secrets = true;
2684
2685 11526 bool do_replay_comment = true;
2686 11526 bool from_active_screen = true;
2687 11526 trigger_secrets_for_screen_internal(create_screen_handles(scr), from_active_screen, high16only, single, do_replay_comment);
2688
2689 // Respect secret state carryovers for active screens.
2690
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11087 times.
11526 if (single >= 0) return;
2691 11087 int flag = mSECRET;
2692 11087 int cmap = scr->map;
2693 11087 int cscr = scr->screen;
2694 11087 int nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
2695 11087 int nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
2696
2697 11087 std::vector<int32_t> done;
2698
2/2
✓ Branch 0 taken 10900 times.
✓ Branch 1 taken 187 times.
11087 bool looped = (nmap==cmap+1 && nscr==cscr);
2699
2700
6/6
✓ Branch 0 taken 629 times.
✓ Branch 1 taken 11010 times.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 552 times.
✓ Branch 4 taken 552 times.
✓ Branch 5 taken 11087 times.
11639 while((nmap!=0) && !looped && !(nscr>=128))
2701 {
2702
9/10
✓ Branch 0 taken 385 times.
✓ Branch 1 taken 167 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 301 times.
✓ Branch 4 taken 74 times.
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 74 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 70 times.
552 if (nmap - 1 == cur_map && is_in_current_region(nscr) && (scr->nocarry&flag)!=flag && !get_screen_state(nscr).triggered_secrets)
2703 {
2704
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
2705
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 trigger_secrets_for_screen_internal(create_screen_handles(get_scr(nscr)), from_active_screen, high16only, single, do_replay_comment);
2706
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 get_screen_state(nscr).triggered_secrets = true;
2707 4 }
2708
2709 552 cmap=nmap;
2710 552 cscr=nscr;
2711 552 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
2712 552 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
2713
2714
2/2
✓ Branch 0 taken 1101 times.
✓ Branch 1 taken 552 times.
1653 for(auto it = done.begin(); it != done.end(); it++)
2715 {
2716
2/2
✓ Branch 0 taken 1024 times.
✓ Branch 1 taken 77 times.
1101 if(*it == ((nmap-1)<<7)+nscr)
2717 77 looped = true;
2718 1101 }
2719
2720
1/2
✓ Branch 0 taken 552 times.
✗ Branch 1 not taken.
552 done.push_back(((nmap-1)<<7)+nscr);
2721 }
2722 11526 }
2723
2724 2437 void trigger_secrets_for_screen(TriggerSource source, int32_t screen, bool high16only, int32_t single)
2725 {
2726 2437 trigger_secrets_for_screen(source, get_scr(screen), high16only, single);
2727 2437 }
2728
2729 17999 void trigger_secrets_for_screen_internal(const screen_handles_t& screen_handles, bool from_active_screen, bool high16only, int32_t single, bool do_replay_comment)
2730 {
2731 17999 mapscr* scr = screen_handles[0].scr;
2732 17999 int screen = scr->screen;
2733
2734 // TODO(replays): No real reason for "do_replay_comment" to exist - I just did not want to update many replays when fixing
2735 // slopes in sideview mode (which required loading nearby screens in loadscr).
2736 // TODO(replays): This should just use `screen`.
2737
3/4
✓ Branch 0 taken 17999 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 535 times.
✓ Branch 3 taken 17464 times.
17999 if (replay_is_active() && do_replay_comment)
2738
4/6
✓ Branch 0 taken 11530 times.
✓ Branch 1 taken 5934 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11530 times.
✓ Branch 4 taken 17464 times.
✗ Branch 5 not taken.
17464 replay_step_comment(fmt::format("trigger secrets scr={}", from_active_screen && scr != special_warp_return_scr ? screen : cur_screen));
2739
2740
2/2
✓ Branch 0 taken 6469 times.
✓ Branch 1 taken 11530 times.
17999 if (from_active_screen)
2741 {
2742 5440178 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
2743 5428648 auto cid = handle.data();
2744 5428648 auto& cmb = handle.combo();
2745
4/4
✓ Branch 0 taken 5426940 times.
✓ Branch 1 taken 229446 times.
✓ Branch 2 taken 1688 times.
✓ Branch 3 taken 182 times.
5658256 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
2746 {
2747 229628 auto& trig = cmb.triggers[idx];
2748
3/4
✓ Branch 0 taken 65534 times.
✓ Branch 1 taken 163912 times.
✓ Branch 2 taken 182 times.
✗ Branch 3 not taken.
229628 if (trig.triggerflags[2] & combotriggerSECRETSTR)
2749 {
2750 163912 do_trigger_combo(handle, idx, ctrigSECRETS);
2751
2/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 163892 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
163912 if(handle.data() != cid) break;
2752 163892 }
2753 229608 }
2754 5428648 });
2755 11530 }
2756
2757 17999 int32_t ft=0; //Flag trigger?
2758 17999 int32_t msflag=0; // Misc. secret flag
2759
2760
2/2
✓ Branch 0 taken 3167824 times.
✓ Branch 1 taken 17999 times.
3185823 for(int32_t i=0; i<176; i++) //Do the 'trigger flags' (non 16-31)
2761 {
2762
4/4
✓ Branch 0 taken 77264 times.
✓ Branch 1 taken 3090560 times.
✓ Branch 2 taken 439 times.
✓ Branch 3 taken 76825 times.
3167824 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2763
2764 // Remember the misc. secret flag; if triggered, use this instead
2765
4/4
✓ Branch 0 taken 114508 times.
✓ Branch 1 taken 2976491 times.
✓ Branch 2 taken 49462 times.
✓ Branch 3 taken 65046 times.
3090999 if(scr->sflag[i]>=mfSECRETS01 && scr->sflag[i]<=mfSECRETS16)
2766 65046 msflag=sSECRET01+(scr->sflag[i]-mfSECRETS01);
2767
4/4
✓ Branch 0 taken 47230 times.
✓ Branch 1 taken 2978723 times.
✓ Branch 2 taken 46999 times.
✓ Branch 3 taken 231 times.
3025953 else if(combobuf[scr->data[i]].flag>=mfSECRETS01 && combobuf[scr->data[i]].flag<=mfSECRETS16)
2768 231 msflag=sSECRET01+(combobuf[scr->data[i]].flag-mfSECRETS01);
2769 else
2770 3025722 msflag=0;
2771
2772
4/4
✓ Branch 0 taken 921256 times.
✓ Branch 1 taken 2169743 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 921184 times.
3090999 if(!high16only || single>=0)
2773 {
2774 2169815 int32_t newflag = -1;
2775
2776
2/2
✓ Branch 0 taken 4339630 times.
✓ Branch 1 taken 2169815 times.
6509445 for(int32_t iter=0; iter<2; ++iter)
2777 {
2778 4339630 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2779
2780
2/2
✓ Branch 0 taken 2169815 times.
✓ Branch 1 taken 2169815 times.
4339630 if(iter==1) checkflag=scr->sflag[i]; //Placed
2781
2782 4339630 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2783
2/2
✓ Branch 0 taken 4327396 times.
✓ Branch 1 taken 12234 times.
4339630 if (ft != -1) //Change the combos for the secret
2784 {
2785 // Use misc. secret flag instead if one is present
2786
2/2
✓ Branch 0 taken 12202 times.
✓ Branch 1 taken 32 times.
12234 if(msflag!=0)
2787 32 ft=msflag;
2788
2789 12234 rpos_handle_t rpos_handle;
2790
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2791 {
2792 5867 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2793 5867 screen_combo_modify_preroutine(rpos_handle);
2794 5867 }
2795
2796
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12234 times.
12234 if(ft==sSECNEXT)
2797 {
2798 scr->data[i]++;
2799 }
2800 else
2801 {
2802 12234 scr->data[i] = scr->secretcombo[ft];
2803 12234 scr->cset[i] = scr->secretcset[ft];
2804 }
2805 12234 newflag = scr->secretflag[ft];
2806
2807
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2808 5867 screen_combo_modify_postroutine(rpos_handle);
2809 12234 }
2810 4339630 }
2811
2812
2/2
✓ Branch 0 taken 2157587 times.
✓ Branch 1 taken 12228 times.
2169815 if(newflag >-1) scr->sflag[i] = newflag; //Tiered secret
2813
2814
2/2
✓ Branch 0 taken 13018890 times.
✓ Branch 1 taken 2169815 times.
15188705 for(int32_t j=1; j<=6; j++) //Layers
2815 {
2816 13018890 mapscr* layer_scr = screen_handles[j].scr;
2817
2/2
✓ Branch 0 taken 3183685 times.
✓ Branch 1 taken 9835205 times.
13018890 if (!layer_scr) continue;
2818
2819
3/4
✓ Branch 0 taken 725 times.
✓ Branch 1 taken 3182960 times.
✓ Branch 2 taken 725 times.
✗ Branch 3 not taken.
3183685 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2820
2821 3183685 int32_t newflag2 = -1;
2822
2823 // Remember the misc. secret flag; if triggered, use this instead
2824
4/4
✓ Branch 0 taken 14180 times.
✓ Branch 1 taken 3169505 times.
✓ Branch 2 taken 4773 times.
✓ Branch 3 taken 9407 times.
3183685 if(layer_scr->sflag[i]>=mfSECRETS01 && layer_scr->sflag[i]<=mfSECRETS16)
2825 9407 msflag=sSECRET01+(layer_scr->sflag[i]-mfSECRETS01);
2826
4/4
✓ Branch 0 taken 126931 times.
✓ Branch 1 taken 3047347 times.
✓ Branch 2 taken 126560 times.
✓ Branch 3 taken 371 times.
3174278 else if(combobuf[layer_scr->data[i]].flag>=mfSECRETS01 && combobuf[layer_scr->data[i]].flag<=mfSECRETS16)
2827 371 msflag=sSECRET01+(combobuf[layer_scr->data[i]].flag-mfSECRETS01);
2828 else
2829 3173907 msflag=0;
2830
2831
2/2
✓ Branch 0 taken 6367370 times.
✓ Branch 1 taken 3183685 times.
9551055 for(int32_t iter=0; iter<2; ++iter)
2832 {
2833 6367370 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2834
2/2
✓ Branch 0 taken 3183685 times.
✓ Branch 1 taken 3183685 times.
6367370 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2835
2836 6367370 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2837
2/2
✓ Branch 0 taken 6366892 times.
✓ Branch 1 taken 478 times.
6367370 if (ft != -1) //Change the combos for the secret
2838 {
2839 // Use misc. secret flag instead if one is present
2840
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 2 times.
478 if(msflag!=0)
2841 2 ft=msflag;
2842
2843
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 478 times.
478 if(ft==sSECNEXT)
2844 {
2845 layer_scr->data[i]++;
2846 }
2847 else
2848 {
2849 478 layer_scr->data[i] = layer_scr->secretcombo[ft];
2850 478 layer_scr->cset[i] = layer_scr->secretcset[ft];
2851 }
2852 478 newflag2 = layer_scr->secretflag[ft];
2853 478 int32_t c=layer_scr->data[i];
2854 478 int32_t cs=layer_scr->cset[i];
2855
2856
3/4
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 406 times.
✗ Branch 3 not taken.
478 if (from_active_screen && combobuf[c].type==cSPINTILE1) //Surely this means we can have spin tiles on layers 3+? Isn't that bad? ~Joe123
2857 {
2858 auto [offx, offy] = translate_screen_coordinates_to_world(screen, COMBOX(i), COMBOY(i));
2859 addenemy(screen,offx,offy,(cs<<12)+eSPINTILE1,combobuf[c].o_tile+zc_max(1,combobuf[c].frames));
2860 }
2861 478 }
2862 6367370 }
2863
2864
2/2
✓ Branch 0 taken 478 times.
✓ Branch 1 taken 3183207 times.
3183685 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered secret
2865 3183685 }
2866 2169815 }
2867 3090999 }
2868
2869 17999 word c = scr->numFFC();
2870
2/2
✓ Branch 0 taken 506903 times.
✓ Branch 1 taken 17999 times.
524902 for(word i=0; i<c; i++) //FFC 'trigger flags'
2871 {
2872
3/4
✓ Branch 0 taken 492983 times.
✓ Branch 1 taken 13920 times.
✓ Branch 2 taken 13920 times.
✗ Branch 3 not taken.
506903 if(single>=0) if(i+176!=single) continue;
2873
2874
3/4
✓ Branch 0 taken 166605 times.
✓ Branch 1 taken 326378 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 166605 times.
492983 if((!high16only)||(single>=0))
2875 {
2876 //for (int32_t iter=0; iter<1; ++iter) // Only one kind of FFC flag now.
2877 {
2878 326378 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
2879 //No placed flags yet
2880
2881 326378 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2882
2/2
✓ Branch 0 taken 326347 times.
✓ Branch 1 taken 31 times.
326378 if (ft != -1) //Change the ffc's combo
2883 {
2884
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(ft==sSECNEXT)
2885 {
2886 zc_ffc_modify(scr->ffcs[i], 1);
2887 }
2888 else
2889 {
2890 31 zc_ffc_set(scr->ffcs[i], scr->secretcombo[ft]);
2891 31 scr->ffcs[i].cset = scr->secretcset[ft];
2892 }
2893 31 }
2894 }
2895 326378 }
2896 492983 }
2897
2898
2/2
✓ Branch 0 taken 15602 times.
✓ Branch 1 taken 2397 times.
17999 if(checktrigger) //Hit all triggers->16-31
2899 {
2900 2397 checktrigger=false;
2901
2902
2/2
✓ Branch 0 taken 2388 times.
✓ Branch 1 taken 9 times.
2397 if(scr->flags6&fTRIGGERF1631)
2903 {
2904 9 int32_t tr = findtrigger(screen); //Normal flags
2905
2906
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 if(tr)
2907 {
2908 5 Z_eventlog("Hit All Triggers->16-31 not fulfilled (%d trigger flag%s remain).\n", tr, tr>1?"s":"");
2909 5 goto endhe;
2910 }
2911 4 }
2912 2392 }
2913
2914
2/2
✓ Branch 0 taken 3166944 times.
✓ Branch 1 taken 17994 times.
3184938 for(int32_t i=0; i<176; i++) // Do the 16-31 secrets
2915 {
2916 //If it's an enemies->secret screen, only do the high 16 if told to
2917 //That way you can have secret and burn/bomb entrance separately
2918 3166944 bool old_enem_secret = get_qr(qr_ENEMIES_SECRET_ONLY_16_31);
2919
6/6
✓ Branch 0 taken 2780624 times.
✓ Branch 1 taken 386320 times.
✓ Branch 2 taken 85184 times.
✓ Branch 3 taken 3081760 times.
✓ Branch 4 taken 19536 times.
✓ Branch 5 taken 65648 times.
3166944 if(((!(old_enem_secret && (scr->flags2&fCLEARSECRET)) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM))
2920 {
2921 3101296 int32_t newflag = -1;
2922
2923
2/2
✓ Branch 0 taken 6202592 times.
✓ Branch 1 taken 3101296 times.
9303888 for(int32_t iter=0; iter<2; ++iter)
2924 {
2925 6202592 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2926
2927
2/2
✓ Branch 0 taken 3101296 times.
✓ Branch 1 taken 3101296 times.
6202592 if(iter==1) checkflag=scr->sflag[i]; //Placed
2928
2929
4/4
✓ Branch 0 taken 161182 times.
✓ Branch 1 taken 6041410 times.
✓ Branch 2 taken 94853 times.
✓ Branch 3 taken 66329 times.
6202592 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
2930 {
2931 66329 rpos_handle_t rpos_handle;
2932
2/2
✓ Branch 0 taken 9951 times.
✓ Branch 1 taken 56378 times.
66329 if (from_active_screen)
2933 {
2934 56378 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2935 56378 screen_combo_modify_preroutine(rpos_handle);
2936 56378 }
2937
2938 66329 scr->data[i] = scr->secretcombo[checkflag-16+4];
2939 66329 scr->cset[i] = scr->secretcset[checkflag-16+4];
2940 66329 newflag = scr->secretflag[checkflag-16+4];
2941
2942
2/2
✓ Branch 0 taken 9951 times.
✓ Branch 1 taken 56378 times.
66329 if (from_active_screen)
2943 56378 screen_combo_modify_postroutine(rpos_handle);
2944 66329 }
2945 6202592 }
2946
2947
2/2
✓ Branch 0 taken 3034991 times.
✓ Branch 1 taken 66305 times.
3101296 if(newflag >-1) scr->sflag[i] = newflag; //Tiered flag
2948
2949
2/2
✓ Branch 0 taken 18607776 times.
✓ Branch 1 taken 3101296 times.
21709072 for(int32_t j=1; j<=6; j++) //Layers
2950 {
2951 18607776 mapscr* layer_scr = screen_handles[j].scr;
2952
2/2
✓ Branch 0 taken 4864640 times.
✓ Branch 1 taken 13743136 times.
18607776 if (!layer_scr) continue;
2953
2954 4864640 int32_t newflag2 = -1;
2955
2956
2/2
✓ Branch 0 taken 9729280 times.
✓ Branch 1 taken 4864640 times.
14593920 for(int32_t iter=0; iter<2; ++iter)
2957 {
2958 9729280 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2959
2960
2/2
✓ Branch 0 taken 4864640 times.
✓ Branch 1 taken 4864640 times.
9729280 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2961
2962
4/4
✓ Branch 0 taken 151244 times.
✓ Branch 1 taken 9578036 times.
✓ Branch 2 taken 131622 times.
✓ Branch 3 taken 19622 times.
9729280 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
2963 {
2964 19622 layer_scr->data[i] = layer_scr->secretcombo[checkflag-16+4];
2965 19622 layer_scr->cset[i] = layer_scr->secretcset[checkflag-16+4];
2966 19622 newflag2 = layer_scr->secretflag[checkflag-16+4];
2967 19622 }
2968 9729280 }
2969
2970
2/2
✓ Branch 0 taken 4845018 times.
✓ Branch 1 taken 19622 times.
4864640 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered flag
2971 4864640 }
2972 3101296 }
2973 3166944 }
2974
2975
2/2
✓ Branch 0 taken 506743 times.
✓ Branch 1 taken 17994 times.
524737 for(word i=0; i<c; i++) // FFCs
2976 {
2977
6/6
✓ Branch 0 taken 466852 times.
✓ Branch 1 taken 39891 times.
✓ Branch 2 taken 15367 times.
✓ Branch 3 taken 491376 times.
✓ Branch 4 taken 3530 times.
✓ Branch 5 taken 11837 times.
506743 if((!(scr->flags2&fCLEARSECRET) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM)
2978 {
2979 494906 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
2980
2981 //No placed flags yet
2982
4/4
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 494838 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 12 times.
494906 if((checkflag > 15)&&(checkflag < 32)) //If we find a flag, change the combo
2983 {
2984
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (from_active_screen)
2985 9 zc_ffc_set(scr->ffcs[i], scr->secretcombo[checkflag - 16 + 4]);
2986 else
2987 3 scr->ffcs[i].data = scr->secretcombo[checkflag - 16 + 4];
2988 12 scr->ffcs[i].cset = scr->secretcset[checkflag-16+4];
2989 12 }
2990 494906 }
2991 524737 }
2992
2993 endhe:
2994
2995
1/2
✓ Branch 0 taken 17999 times.
✗ Branch 1 not taken.
17999 if (scr->flags4&fDISABLETIME) //Finish timed warp if 'Secrets Disable Timed Warp'
2996 {
2997 if (from_active_screen)
2998 activated_timed_warp = true;
2999 scr->timedwarptics = 0;
3000 }
3001 17999 }
3002
3003 // x,y are world coordinates.
3004 // Returns true if there is a flag (either combo, screen, or ffc) at (x, y).
3005 // Out parameters will be set if the flag is Trigger->Self, which modifies how secrets will be triggered.
3006 13503640 static bool has_flag_trigger(int32_t x, int32_t y, int32_t flag, rpos_t& out_rpos, bool& out_single16)
3007 {
3008
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13503640 times.
13503640 if (!is_in_world_bounds(x, y)) return false;
3009
3010 13503640 bool found_cflag = false;
3011 13503640 bool found_nflag = false;
3012 13503640 bool single16 = false;
3013 13503640 rpos_t rpos = rpos_t::None;
3014
3015
2/2
✓ Branch 0 taken 13501556 times.
✓ Branch 1 taken 94513288 times.
108014844 for (int32_t layer = -1; layer < 6; layer++)
3016 {
3017
2/2
✓ Branch 0 taken 94511204 times.
✓ Branch 1 taken 2084 times.
94513288 if (MAPFLAG2(layer, x, y) == flag)
3018 {
3019 2084 found_nflag = true;
3020 2084 break;
3021 }
3022 94511204 }
3023
3024
2/2
✓ Branch 0 taken 13503336 times.
✓ Branch 1 taken 94524204 times.
108027540 for (int32_t layer = -1; layer < 6; layer++)
3025 {
3026
2/2
✓ Branch 0 taken 94523900 times.
✓ Branch 1 taken 304 times.
94524204 if (MAPCOMBOFLAG2(layer, x, y) == flag)
3027 {
3028 304 found_cflag = true;
3029 304 break;
3030 }
3031 94523900 }
3032
3033
2/2
✓ Branch 0 taken 94525480 times.
✓ Branch 1 taken 13503640 times.
108029120 for (int32_t i=-1; i<6; i++) // Look for Trigger->Self on all layers
3034 {
3035
2/2
✓ Branch 0 taken 94510892 times.
✓ Branch 1 taken 14588 times.
94525480 if (found_nflag) // Trigger->Self (a.k.a Singular) is inherent
3036 {
3037
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14476 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
14588 if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE) && (MAPFLAG2(i, x, y) == flag))
3038 {
3039 112 rpos = COMBOPOS_REGION(x, y);
3040 112 }
3041
3/4
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 14424 times.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
14476 else if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE16) && (MAPFLAG2(i, x, y) == flag))
3042 {
3043 52 rpos = COMBOPOS_REGION(x, y);
3044 52 single16 = true;
3045 52 }
3046 14588 }
3047
3048
2/2
✓ Branch 0 taken 94523352 times.
✓ Branch 1 taken 2128 times.
94525480 if (found_cflag) // Trigger->Self (a.k.a Singular) is non-inherent
3049 {
3050
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 1873 times.
✓ Branch 2 taken 255 times.
✗ Branch 3 not taken.
2128 if ((MAPFLAG2(i, x, y) == mfSINGLE) && (MAPCOMBOFLAG2(i, x, y) == flag))
3051 {
3052 255 rpos = COMBOPOS_REGION(x, y);
3053 255 }
3054
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1853 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
1873 else if ((MAPFLAG2(i, x, y) == mfSINGLE16) && (MAPCOMBOFLAG2(i, x, y) == flag))
3055 {
3056 20 rpos = COMBOPOS_REGION(x, y);
3057 20 single16 = true;
3058 20 }
3059 2128 }
3060 94525480 }
3061
3062 13503640 out_rpos = rpos;
3063 13503640 out_single16 = single16;
3064
4/4
✓ Branch 0 taken 13501556 times.
✓ Branch 1 taken 2084 times.
✓ Branch 2 taken 13501254 times.
✓ Branch 3 taken 302 times.
13503640 return found_nflag || found_cflag || MAPFFCOMBOFLAG(x,y) == flag;
3065 13503640 }
3066
3067 4456182 bool trigger_secrets_if_flag(int32_t x, int32_t y, int32_t flag, bool setflag)
3068 {
3069
8/8
✓ Branch 0 taken 4455942 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 4454045 times.
✓ Branch 3 taken 1897 times.
✓ Branch 4 taken 4453525 times.
✓ Branch 5 taken 520 times.
✓ Branch 6 taken 952 times.
✓ Branch 7 taken 4452573 times.
4456182 if (x < -16 || y < -16 || x >= world_w || y >= world_h) return false;
3070
3071 4452573 mapscr* scr = NULL;
3072 4452573 int32_t screen = -1;
3073 4452573 rpos_t trigger_rpos = rpos_t::None;
3074 4452573 bool single16 = false;
3075
3076 4452573 std::vector<std::pair<int, int>> coords;
3077
1/2
✓ Branch 0 taken 4452573 times.
✗ Branch 1 not taken.
4452573 coords.push_back({x, y});
3078
1/2
✓ Branch 0 taken 4452573 times.
✗ Branch 1 not taken.
4452573 coords.push_back({x + 15, y});
3079
1/2
✓ Branch 0 taken 4452573 times.
✗ Branch 1 not taken.
4452573 coords.push_back({x, y + 15});
3080
1/2
✓ Branch 0 taken 4452573 times.
✗ Branch 1 not taken.
4452573 coords.push_back({x + 15, y + 15});
3081 4452573 std::vector<rpos_t> rposes_seen;
3082
2/2
✓ Branch 0 taken 4450176 times.
✓ Branch 1 taken 17805010 times.
84452582 for (auto [x, y] : coords)
3083 {
3084
2/4
✓ Branch 0 taken 17805010 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17805010 times.
✗ Branch 3 not taken.
35610020 rpos_t rpos = COMBOPOS_REGION_B(x, y);
3085
2/2
✓ Branch 0 taken 17592661 times.
✓ Branch 1 taken 212349 times.
17805010 if (rpos == rpos_t::None)
3086 212349 continue;
3087
3088
4/6
✓ Branch 0 taken 17592661 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17592661 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 17592650 times.
35185322 if (MAPFFCOMBOFLAG(x, y) == flag)
3089 {
3090
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 screen = get_screen_for_world_xy(x, y);
3091 11 break;
3092 }
3093
3094 17592650 bool seen = false;
3095
2/2
✓ Branch 0 taken 13503640 times.
✓ Branch 1 taken 22120356 times.
35623996 for (rpos_t r : rposes_seen)
3096 {
3097
2/2
✓ Branch 0 taken 18031346 times.
✓ Branch 1 taken 4089010 times.
22120356 if (r == rpos)
3098 {
3099 4089010 seen = true;
3100 4089010 break;
3101 }
3102 }
3103
2/2
✓ Branch 0 taken 13503640 times.
✓ Branch 1 taken 4089010 times.
17592650 if (seen)
3104 4089010 continue;
3105
3106
1/2
✓ Branch 0 taken 13503640 times.
✗ Branch 1 not taken.
13503640 rposes_seen.push_back(rpos);
3107
4/6
✓ Branch 0 taken 13503640 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13503640 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2386 times.
✓ Branch 5 taken 13501254 times.
27007280 if (has_flag_trigger(x, y, flag, trigger_rpos, single16))
3108 {
3109
2/4
✓ Branch 0 taken 2386 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2386 times.
✗ Branch 3 not taken.
4772 screen = get_screen_for_world_xy(x, y);
3110 2386 break;
3111 }
3112 }
3113
3114
3/4
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4450176 times.
✓ Branch 2 taken 2397 times.
✗ Branch 3 not taken.
4452573 if (screen != -1) scr = get_scr(screen);
3115
2/2
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4450176 times.
4452573 if (!scr) return false;
3116
3117
2/2
✓ Branch 0 taken 1958 times.
✓ Branch 1 taken 439 times.
2397 if (trigger_rpos == rpos_t::None)
3118 {
3119 1958 checktrigger = true;
3120
1/2
✓ Branch 0 taken 1958 times.
✗ Branch 1 not taken.
1958 trigger_secrets_for_screen(TriggerSource::Unspecified, screen);
3121 1958 }
3122 else
3123 {
3124 439 checktrigger = true;
3125
2/4
✓ Branch 0 taken 439 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 439 times.
✗ Branch 3 not taken.
439 trigger_secrets_for_screen(TriggerSource::Singular, scr, single16, RPOS_TO_POS(trigger_rpos));
3126 }
3127
3128
1/2
✓ Branch 0 taken 2397 times.
✗ Branch 1 not taken.
2397 sfx(scr->secretsfx);
3129
3130
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2391 times.
2397 if(scr->flags6&fTRIGGERFPERM)
3131 {
3132
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 int32_t flags_remaining = findtrigger(screen); //Normal flags
3133
3134
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (flags_remaining)
3135 {
3136
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 Z_eventlog("Hit All Triggers->Perm Secret not fulfilled (%d trigger flag%s remain).\n", flags_remaining, flags_remaining>1?"s":"");
3137 3 setflag=false;
3138 3 }
3139
3140 // Only actually trigger secrets now if 1) all triggers are gone and 2) QR qr_ALLTRIG_PERMSEC_NO_TEMP is off, in
3141 // which case only the screen state for mSECRET may be set below.
3142
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 if (!flags_remaining && !get_qr(qr_ALLTRIG_PERMSEC_NO_TEMP))
3143 {
3144 trigger_secrets_for_screen(TriggerSource::Unspecified, scr, scr->flags6&fTRIGGERF1631, -1);
3145 }
3146 6 }
3147
3148
5/6
✓ Branch 0 taken 2292 times.
✓ Branch 1 taken 105 times.
✓ Branch 2 taken 2292 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1108 times.
✓ Branch 5 taken 1184 times.
2397 if (setflag && canPermSecret(cur_dmap, screen))
3149
2/2
✓ Branch 0 taken 721 times.
✓ Branch 1 taken 463 times.
1905 if(!(scr->flags5&fTEMPSECRETS))
3150
1/2
✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
721 setmapflag(scr, mSECRET);
3151
3152 2397 return true;
3153 4456182 }
3154
3155 14796824 void update_slopes()
3156 {
3157
2/2
✓ Branch 0 taken 142356 times.
✓ Branch 1 taken 14796824 times.
14939180 for (auto& p : slopes)
3158 {
3159 142356 slope_object& s = p.second;
3160 142356 s.updateslope(); //sets old x/y poses
3161 }
3162 14796824 }
3163
3164 14390603 void update_freeform_combos()
3165 {
3166 14390603 ffscript_engine(false);
3167
2/2
✓ Branch 0 taken 24172 times.
✓ Branch 1 taken 14366431 times.
14390603 if ( !FFCore.system_suspend[susptUPDATEFFC] )
3168 {
3169 14366431 int wrap_right = world_w + 32;
3170 14366431 int wrap_bottom = world_h + 32;
3171
3172 485495057 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
3173 471128626 mapscr* scr = ffc_handle.scr;
3174 471128626 ffcdata& thisffc = *ffc_handle.ffc;
3175
3176 // Combo 0?
3177
2/2
✓ Branch 0 taken 44992137 times.
✓ Branch 1 taken 426136489 times.
471128626 if(thisffc.data==0)
3178 426136489 return;
3179
3180 // Changer?
3181
2/2
✓ Branch 0 taken 543029 times.
✓ Branch 1 taken 44449108 times.
44992137 if(thisffc.flags&ffc_changer)
3182 543029 return;
3183
3184 // Stationary?
3185
2/2
✓ Branch 0 taken 9844 times.
✓ Branch 1 taken 44439264 times.
44449108 if(thisffc.flags&ffc_stationary)
3186 9844 return;
3187
3188 // Frozen because Hero's holding up an item?
3189
3/4
✓ Branch 0 taken 138282 times.
✓ Branch 1 taken 44300982 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 138282 times.
44439264 if(Hero.getHoldClk()>0 && (thisffc.flags&ffc_ignoreholdup)==0)
3190 138282 return;
3191
3192 // Check for changers
3193
2/2
✓ Branch 0 taken 29543718 times.
✓ Branch 1 taken 14757264 times.
44300982 if (thisffc.link==0)
3194 {
3195 442453057 for_some_ffcs([&](const ffc_handle_t& other_ffc_handle) {
3196
2/2
✓ Branch 0 taken 14755728 times.
✓ Branch 1 taken 412940065 times.
427695793 if (ffc_handle.id == other_ffc_handle.id)
3197 14755728 return true;
3198
3199 412940065 ffcdata& otherffc = *other_ffc_handle.ffc;
3200 // Combo 0?
3201
2/2
✓ Branch 0 taken 144689563 times.
✓ Branch 1 taken 268250502 times.
412940065 if(otherffc.data==0)
3202 268250502 return true;
3203
3204 // Not a changer?
3205
2/2
✓ Branch 0 taken 140701386 times.
✓ Branch 1 taken 3988177 times.
144689563 if(!(otherffc.flags&ffc_changer))
3206 140701386 return true;
3207
3208 // Ignore this changer?
3209
4/4
✓ Branch 0 taken 546579 times.
✓ Branch 1 taken 3441598 times.
✓ Branch 2 taken 299257 times.
✓ Branch 3 taken 3142341 times.
3988177 if((otherffc.x.getInt()==thisffc.changer_x&&otherffc.y.getInt()==thisffc.changer_y) || thisffc.flags&ffc_ignorechanger)
3210 845836 return true;
3211
3212
3/4
✓ Branch 0 taken 2721043 times.
✓ Branch 1 taken 421298 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3562 times.
3145903 if((isonline(thisffc.x.getZLong(), thisffc.y.getZLong(), thisffc.prev_changer_x, thisffc.prev_changer_y, otherffc.x.getZLong(), otherffc.y.getZLong()) || // Along the line, or...
3213 ( // At exactly the same position,
3214
2/2
✓ Branch 0 taken 208792 times.
✓ Branch 1 taken 2512251 times.
2721043 (thisffc.x==otherffc.x && thisffc.y==otherffc.y))
3215
2/2
✓ Branch 0 taken 2303459 times.
✓ Branch 1 taken 2512251 times.
208792 ||
3216 //or imprecision and close enough
3217
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5024502 ( (thisffc.flags&ffc_imprecisionchanger) && ((abs(thisffc.x.getZLong() - otherffc.x.getZLong()) < 10000) && abs(thisffc.y.getZLong() - otherffc.y.getZLong()) < 10000) )
3218 )
3219 && //and...
3220
2/2
✓ Branch 0 taken 3562 times.
✓ Branch 1 taken 2721195 times.
2724757 (thisffc.prev_changer_x>-10000000 && thisffc.prev_changer_y>-10000000)) // This isn't the first frame on this screen
3221 {
3222 3562 zc_ffc_changer(thisffc, otherffc, ffc_handle.id, other_ffc_handle.id);
3223 3562 return false;
3224 }
3225
3226 2721195 return true;
3227 426679695 });
3228 14757264 }
3229
3230
2/2
✓ Branch 0 taken 29543718 times.
✓ Branch 1 taken 14757264 times.
44300982 ffcdata* linked_ffc = thisffc.link ? get_ffc_handle(thisffc.link - 1).ffc : nullptr;
3231
4/4
✓ Branch 0 taken 14757264 times.
✓ Branch 1 taken 29543718 times.
✓ Branch 2 taken 14679974 times.
✓ Branch 3 taken 14863744 times.
44300982 if (linked_ffc ? !linked_ffc->delay : !thisffc.delay)
3232 {
3233
4/4
✓ Branch 0 taken 182609 times.
✓ Branch 1 taken 14681135 times.
✓ Branch 2 taken 85331 times.
✓ Branch 3 taken 97278 times.
14863744 if(thisffc.link && (thisffc.link-1) != ffc_handle.id)
3234 {
3235 97278 thisffc.prev_changer_x = thisffc.x.getZLong();
3236 97278 thisffc.prev_changer_y = thisffc.y.getZLong();
3237 97278 thisffc.x += linked_ffc->vx;
3238 97278 thisffc.y += linked_ffc->vy;
3239 97278 }
3240 else
3241 {
3242 14766466 thisffc.prev_changer_x = thisffc.x.getZLong();
3243 14766466 thisffc.prev_changer_y = thisffc.y.getZLong();
3244 14766466 thisffc.x += thisffc.vx;
3245 14766466 thisffc.y += thisffc.vy;
3246 14766466 thisffc.vx += thisffc.ax;
3247 14766466 thisffc.vy += thisffc.ay;
3248
3249
3250
2/2
✓ Branch 0 taken 444012 times.
✓ Branch 1 taken 14322454 times.
14766466 if(get_qr(qr_OLD_FFC_SPEED_CAP))
3251 {
3252
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx>128) thisffc.vx=128;
3253
3254
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx<-128) thisffc.vx=-128;
3255
3256
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy>128) thisffc.vy=128;
3257
3258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy<-128) thisffc.vy=-128;
3259 14322454 }
3260 }
3261 14863744 }
3262 else
3263 {
3264
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 76129 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1161 times.
29437238 if(!thisffc.link || (thisffc.link-1) == ffc_handle.id)
3265 76129 thisffc.delay--;
3266 }
3267
3268 // Check if the FFC's off the side of the screen
3269
3270 // Left
3271
2/2
✓ Branch 0 taken 10449 times.
✓ Branch 1 taken 14930585 times.
14941034 if(thisffc.x<-32)
3272 {
3273
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 10196 times.
10449 if(scr->flags6&fWRAPAROUNDFF)
3274 {
3275 253 thisffc.x = wrap_right+(thisffc.x+32);
3276 253 thisffc.solid_update(false);
3277 253 thisffc.prev_changer_y = thisffc.y.getZLong();
3278 // Re-enable previous changer
3279 253 thisffc.changer_x = -1000;
3280 253 thisffc.changer_y = -1000;
3281 253 }
3282
2/2
✓ Branch 0 taken 10127 times.
✓ Branch 1 taken 69 times.
10196 else if(thisffc.x<-64)
3283 {
3284 69 zc_ffc_set(thisffc, 0);
3285 69 thisffc.flags&=~ffc_carryover;
3286 69 }
3287 10449 }
3288 // Right
3289
2/2
✓ Branch 0 taken 14930404 times.
✓ Branch 1 taken 181 times.
14930585 else if(thisffc.x>=wrap_right)
3290 {
3291
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 53 times.
181 if(scr->flags6&fWRAPAROUNDFF)
3292 {
3293 128 thisffc.x = thisffc.x-wrap_right-32;
3294 128 thisffc.solid_update(false);
3295 128 thisffc.prev_changer_y = thisffc.y.getZLong();
3296 128 thisffc.changer_x = -1000;
3297 128 thisffc.changer_y = -1000;
3298 128 }
3299 else
3300 {
3301 53 zc_ffc_set(thisffc, 0);
3302 53 thisffc.flags&=~ffc_carryover;
3303 }
3304 181 }
3305
3306 // Top
3307
2/2
✓ Branch 0 taken 25480 times.
✓ Branch 1 taken 14915554 times.
14941034 if(thisffc.y<-32)
3308 {
3309
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25472 times.
25480 if(scr->flags6&fWRAPAROUNDFF)
3310 {
3311 8 thisffc.y = wrap_bottom+(thisffc.y+32);
3312 8 thisffc.solid_update(false);
3313 8 thisffc.prev_changer_x = thisffc.x.getZLong();
3314 8 thisffc.changer_x = -1000;
3315 8 thisffc.changer_y = -1000;
3316 8 }
3317
2/2
✓ Branch 0 taken 25155 times.
✓ Branch 1 taken 317 times.
25472 else if(thisffc.y<-64)
3318 {
3319 317 zc_ffc_set(thisffc, 0);
3320 317 thisffc.flags&=~ffc_carryover;
3321 317 }
3322 25480 }
3323 // Bottom
3324
2/2
✓ Branch 0 taken 14914710 times.
✓ Branch 1 taken 844 times.
14915554 else if(thisffc.y>=wrap_bottom)
3325 {
3326
2/2
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 91 times.
844 if(scr->flags6&fWRAPAROUNDFF)
3327 {
3328 753 thisffc.y = thisffc.y-wrap_bottom-32;
3329 753 thisffc.solid_update(false);
3330 753 thisffc.prev_changer_y = thisffc.x.getZLong();
3331 753 thisffc.changer_x = -1000;
3332 753 thisffc.changer_y = -1000;
3333 753 }
3334 else
3335 {
3336 91 zc_ffc_set(thisffc, 0);
3337 91 thisffc.flags&=~ffc_carryover;
3338 }
3339 844 }
3340 14941034 thisffc.solid_update();
3341 441768678 });
3342 14366431 }
3343 14390603 }
3344
3345 2098420 bool hitcombo(int32_t x, int32_t y, int32_t combotype, byte layers)
3346 {
3347
2/2
✓ Branch 0 taken 14685796 times.
✓ Branch 1 taken 2097896 times.
16783692 for(int q = 0; q < 7; ++q)
3348 {
3349
2/2
✓ Branch 0 taken 12587376 times.
✓ Branch 1 taken 2098420 times.
14685796 if(layers&(1<<q)) //if layer is to be checked
3350
2/2
✓ Branch 0 taken 2097896 times.
✓ Branch 1 taken 524 times.
2098420 if(COMBOTYPE2(q-1,x,y)==combotype) //matching type
3351 524 return true;
3352 14685272 }
3353 2097896 return false;
3354 2098420 }
3355
3356 419684 int gethitcombo(int32_t x, int32_t y, int32_t combotype, byte layers)
3357 {
3358
2/2
✓ Branch 0 taken 2937788 times.
✓ Branch 1 taken 419684 times.
3357472 for(int q = 0; q < 7; ++q)
3359 {
3360
2/2
✓ Branch 0 taken 2518104 times.
✓ Branch 1 taken 419684 times.
2937788 if(layers&(1<<q)) //if layer is to be checked
3361
1/2
✓ Branch 0 taken 419684 times.
✗ Branch 1 not taken.
419684 if(COMBOTYPE2(q-1,x,y)==combotype) //matching type
3362 return MAPCOMBO2(q-1,x,y);
3363 2937788 }
3364 419684 return -1;
3365 419684 }
3366
3367 bool hitflag(int32_t x, int32_t y, int32_t flagtype, byte layers)
3368 {
3369 for(int q = 0; q < 7; ++q)
3370 {
3371 if(layers&(1<<q)) //if layer is to be checked
3372 if(MAPFLAG2(q-1,x,y)==flagtype||MAPCOMBOFLAG2(q-1,x,y)==flagtype) //matching flag
3373 return true;
3374 }
3375 return false;
3376 }
3377
3378 231 optional<int> nextscr(int screen, int dir)
3379 {
3380 231 auto [m, s] = nextscr2(cur_map, screen, dir);
3381
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231 times.
231 if (m == -1) return nullopt;
3382 462 return (m<<7) + s;
3383 231 }
3384
3385 1058 std::pair<int32_t, int32_t> nextscr2(int32_t dir)
3386 {
3387 1058 int32_t map = cur_map;
3388
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1058 times.
1058 int32_t screen = screenscrolling ? scrolling_hero_screen : hero_screen;
3389 1058 return nextscr2(map, screen, dir);
3390 }
3391
3392 5570 std::pair<int32_t, int32_t> nextscr2(int map, int screen, int32_t dir)
3393 {
3394 5570 screen = screen_index_direction(screen, (direction)dir);
3395
3396 // need to check for screens on other maps, 's' not valid, etc.
3397 5570 int32_t index = (hero_scr->sidewarpindex >> (dir*2))&3;
3398
3399 // Fun fact: when a scrolling warp is triggered, this function
3400 // is never even called! - Saf
3401
2/2
✓ Branch 0 taken 3322 times.
✓ Branch 1 taken 2248 times.
6114 if(hero_scr->sidewarptype[index] == 3) // scrolling warp
3402 {
3403
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 525 times.
✓ Branch 3 taken 545 times.
✓ Branch 4 taken 696 times.
2248 switch(dir)
3404 {
3405 case up:
3406
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 399 times.
482 if(!(hero_scr->flags2&wfUP)) goto nowarp;
3407
3408 83 break;
3409
3410 case down:
3411
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 446 times.
525 if(!(hero_scr->flags2&wfDOWN)) goto nowarp;
3412
3413 79 break;
3414
3415 case left:
3416
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 336 times.
545 if(!(hero_scr->flags2&wfLEFT)) goto nowarp;
3417
3418 209 break;
3419
3420 case right:
3421
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 523 times.
696 if(!(hero_scr->flags2&wfRIGHT)) goto nowarp;
3422
3423 173 break;
3424 }
3425
3426 544 map = DMaps[hero_scr->sidewarpdmap[index]].map;
3427 544 screen = hero_scr->sidewarpscr[index] + DMaps[hero_scr->sidewarpdmap[index]].xoff;
3428 544 }
3429
3430 nowarp:
3431
4/4
✓ Branch 0 taken 5506 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 5394 times.
5570 if(screen<0||screen>=128)
3432 176 return {-1, -1};
3433
3434 5394 return {map, screen};
3435 5570 }
3436
3437 401 optional<int> nextscr_mi(int mi, int dir)
3438 {
3439 401 int map = mi/MAPSCRSNORMAL;
3440 401 int screen = mi%MAPSCRSNORMAL;
3441 401 auto [m, s] = nextscr2(map, screen, dir);
3442
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if (m == -1) return nullopt;
3443 800 return (m<<7) + s;
3444 401 }
3445
3446 2110 void bombdoor(int32_t x,int32_t y)
3447 {
3448
2/2
✓ Branch 0 taken 2090 times.
✓ Branch 1 taken 20 times.
2110 if (!is_in_world_bounds(x, y))
3449 20 return;
3450
3451 2090 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
3452 2090 mapscr* scr = rpos_handle.scr;
3453 2090 int screen = scr->screen;
3454 2898 auto [x0, y0] = translate_screen_coordinates_to_world(rpos_handle.screen);
3455 #define CHECK_RECT(x,y,rx1,ry1,rx2,ry2) (isinRect(x,y,x0+rx1,y0+ry1,x0+rx2,y0+ry2))
3456
3457
12/12
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 2011 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 69 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 69 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 69 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 69 times.
2090 if(scr->door[0]==dBOMB && CHECK_RECT(x,y,100,0,139,48))
3458 {
3459 69 scr->door[0]=dBOMBED;
3460 69 putdoor(scr, scrollbuf, 0, dBOMBED);
3461 69 setmapflag(scr, mDOOR_UP);
3462 69 markBmap(-1, screen);
3463
3464
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 if(auto v = nextscr(screen, up))
3465 {
3466 69 setmapflag_mi(*v, mDOOR_DOWN);
3467 69 markBmap(-1,*v-(get_currdmap()<<7));
3468 69 }
3469 69 }
3470
3471
12/12
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2041 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 39 times.
2090 if(scr->door[1]==dBOMB && CHECK_RECT(x,y,100,112,139,176))
3472 {
3473 39 scr->door[1]=dBOMBED;
3474 39 putdoor(scr, scrollbuf, 1, dBOMBED);
3475 39 setmapflag(scr, mDOOR_DOWN);
3476 39 markBmap(-1, rpos_handle.screen);
3477
3478
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if(auto v = nextscr(rpos_handle.screen, down))
3479 {
3480 39 setmapflag_mi(*v, mDOOR_UP);
3481 39 markBmap(-1,*v-(get_currdmap()<<7));
3482 39 }
3483 39 }
3484
3485
12/12
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 2023 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 51 times.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 51 times.
2090 if(scr->door[2]==dBOMB && CHECK_RECT(x,y,0,60,48,98))
3486 {
3487 51 scr->door[2]=dBOMBED;
3488 51 putdoor(scr, scrollbuf, 2, dBOMBED);
3489 51 setmapflag(scr, mDOOR_LEFT);
3490 51 markBmap(-1, rpos_handle.screen);
3491
3492
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto v = nextscr(rpos_handle.screen, left))
3493 {
3494 51 setmapflag_mi(*v, mDOOR_RIGHT);
3495 51 markBmap(-1,*v-(get_currdmap()<<7));
3496 51 }
3497 51 }
3498
3499
12/12
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2004 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 72 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 72 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 72 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 72 times.
2090 if(scr->door[3]==dBOMB && CHECK_RECT(x,y,192,60,240,98))
3500 {
3501 72 scr->door[3]=dBOMBED;
3502 72 putdoor(scr, scrollbuf, 3, dBOMBED);
3503 72 setmapflag(scr, mDOOR_RIGHT);
3504 72 markBmap(-1, rpos_handle.screen);
3505
3506
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if(auto v = nextscr(rpos_handle.screen, right))
3507 {
3508 72 setmapflag_mi(*v, mDOOR_LEFT);
3509 72 markBmap(-1,*v-(get_currdmap()<<7));
3510 72 }
3511 72 }
3512 2110 }
3513
3514 6375200919 void draw_cmb(BITMAP* dest, int32_t x, int32_t y, int32_t cid, int32_t cset,
3515 bool over, bool transp)
3516 {
3517
2/2
✓ Branch 0 taken 3302815909 times.
✓ Branch 1 taken 3072385010 times.
6375200919 if(over)
3518 {
3519
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3302815909 times.
3302815909 if(combobuf[cid].animflags & AF_TRANSPARENT)
3520 transp = !transp;
3521
2/2
✓ Branch 0 taken 319148412 times.
✓ Branch 1 taken 2983667497 times.
3302815909 if(transp)
3522 319148412 overcombotranslucent(dest, x, y, cid, cset, 128);
3523 2983667497 else overcombo(dest, x, y, cid, cset);
3524 3302815909 }
3525 3072385010 else putcombo(dest, x, y, cid, cset);
3526 6375200919 }
3527 6375209367 void draw_cmb_pos(BITMAP* dest, int32_t x, int32_t y, rpos_t rpos, int32_t cid,
3528 int32_t cset, byte layer, bool over, bool transp)
3529 {
3530
2/2
✓ Branch 0 taken 750098459 times.
✓ Branch 1 taken 5625110908 times.
6375209367 if (rpos != rpos_t::None)
3531 {
3532 5625110908 rpos_t plrpos = COMBOPOS_REGION_B(Hero.x+8, Hero.y+8);
3533
2/2
✓ Branch 0 taken 749524 times.
✓ Branch 1 taken 5624361384 times.
5625110908 if (plrpos != rpos_t::None)
3534 {
3535 5624361384 bool dosw = false;
3536
4/4
✓ Branch 0 taken 52860 times.
✓ Branch 1 taken 5624308524 times.
✓ Branch 2 taken 44412 times.
✓ Branch 3 taken 8448 times.
5624361384 if (rpos == hooked_comborpos && (hooked_layerbits & (1<<layer)))
3537 {
3538
1/2
✓ Branch 0 taken 8448 times.
✗ Branch 1 not taken.
8448 if(hooked_undercombos[layer] > -1)
3539 {
3540 draw_cmb(dest, x, y,
3541 hooked_undercombos[layer], hooked_undercombos[layer+7], over, transp);
3542 }
3543 8448 dosw = true;
3544 8448 }
3545
4/4
✓ Branch 0 taken 31925697 times.
✓ Branch 1 taken 5592427239 times.
✓ Branch 2 taken 8448 times.
✓ Branch 3 taken 31917249 times.
5624352936 else if (rpos == plrpos && (hooked_layerbits & (1<<(layer+8))))
3546 {
3547 8448 dosw = true;
3548 8448 }
3549
2/2
✓ Branch 0 taken 5624344488 times.
✓ Branch 1 taken 16896 times.
5624361384 if (dosw)
3550 {
3551
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 16896 times.
✗ Branch 3 not taken.
16896 switch (Hero.switchhookstyle)
3552 {
3553 default: case swPOOF:
3554 break; //Nothing special here
3555 case swFLICKER:
3556 {
3557
2/2
✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 8448 times.
16896 if(abs(Hero.switchhookclk-33)&0b1000)
3558 8448 break; //Drawn this frame
3559 8448 return; //Not drawn this frame
3560 }
3561 case swRISE:
3562 {
3563 //Draw rising up
3564 y -= 8-(abs(Hero.switchhookclk-32)/4);
3565 break;
3566 }
3567 }
3568 8448 }
3569 5624352936 }
3570 5625102460 }
3571
3572 6375200919 draw_cmb(dest, x, y, cid, cset, over, transp);
3573 6375209367 }
3574
3575 // `draw_cmb_pos` only does meaningful work if the combo being drawn is within the bounds of
3576 // the `bmp` bitmap. However, even getting to the point where `puttile16` (for example) knows
3577 // to cull is somewhat expensive. Since it can only draw 16x16 pixels, we can do the equivalent
3578 // culling here by determining the rows/columns that are within the bitmap bounds. This nets
3579 // on the order of ~30 FPS in uncapped mode on my machine, depending on the viewport/region size.
3580 //
3581 // These two inequalities must be true for `draw_cmb_pos` to do anything useful:
3582 //
3583 // -16 < comboPositionX*16 + x < bitmapWidth
3584 // -16 < comboPositionY*16 + y < bitmapHeight
3585 //
3586 // The following start/end values are derived directly from the above.
3587 //
3588 // `x` and `y` are the offsets the combos will be drawn into the bitmap.
3589 39427398 static void get_bounds_for_draw_cmb_calls(BITMAP* bmp, int x, int y, int& start_x, int& end_x, int& start_y, int& end_y)
3590 {
3591 // if (bmp->clip)
3592 // {
3593 // start_x = MAX(0, ceil((bmp->cl - 15 - x) / 16.0));
3594 // end_x = MIN(16, ceil((bmp->cr - x) / 16.0));
3595 // start_y = MAX(0, ceil((bmp->ct - 15 - y) / 16.0));
3596 // end_y = MIN(11, ceil((bmp->cb - y) / 16.0));
3597 // return;
3598 // }
3599
3600
2/2
✓ Branch 0 taken 2167250 times.
✓ Branch 1 taken 37260148 times.
39427398 start_x = MAX(0, ceil((-15 - x) / 16.0));
3601
2/2
✓ Branch 0 taken 2176433 times.
✓ Branch 1 taken 37250965 times.
39427398 end_x = MIN(16, ceil((bmp->w - x) / 16.0));
3602
2/2
✓ Branch 0 taken 38038824 times.
✓ Branch 1 taken 1388574 times.
39427398 start_y = MAX(0, ceil((-15 - y) / 16.0));
3603
2/2
✓ Branch 0 taken 1677524 times.
✓ Branch 1 taken 37749874 times.
39427398 end_y = MIN(11, ceil((bmp->h - y) / 16.0));
3604 39427398 }
3605
3606 186798379 void do_ffc_layer(BITMAP* bmp, int32_t layer, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3607 {
3608
1/2
✓ Branch 0 taken 186798379 times.
✗ Branch 1 not taken.
186798379 if(!show_ffcs) return;
3609 186798379 mapscr* scr = screen_handle.scr;
3610 186798379 mapscr* base_scr = screen_handle.base_scr;
3611
3612 186798379 y += playing_field_offset;
3613
3614 186798379 bool is_bg_layer = layer < -1;
3615
2/2
✓ Branch 0 taken 33897093 times.
✓ Branch 1 taken 152901286 times.
186798379 int real_layer = is_bg_layer ? abs(layer) : layer;
3616
2/2
✓ Branch 0 taken 186798379 times.
✓ Branch 1 taken 5581006546 times.
5767804925 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3617 {
3618
2/2
✓ Branch 0 taken 5375509246 times.
✓ Branch 1 taken 205497300 times.
5581006546 if (base_scr->ffcs[i].data == 0)
3619 5375509246 continue;
3620
4/4
✓ Branch 0 taken 37360890 times.
✓ Branch 1 taken 168136410 times.
✓ Branch 2 taken 18682926 times.
✓ Branch 3 taken 18677964 times.
205497300 if(real_layer == 2 && (is_bg_layer != XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG)))
3621 18677964 continue;
3622
4/4
✓ Branch 0 taken 37360890 times.
✓ Branch 1 taken 149458446 times.
✓ Branch 2 taken 18682926 times.
✓ Branch 3 taken 18677964 times.
186819336 else if (real_layer == 3 && (is_bg_layer != XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)))
3623 18677964 continue;
3624
4/4
✓ Branch 0 taken 149463408 times.
✓ Branch 1 taken 18677964 times.
✓ Branch 2 taken 18682926 times.
✓ Branch 3 taken 130780482 times.
168141372 if (real_layer > -1 && base_scr->ffcs[i].layer != real_layer)
3625 130780482 continue;
3626
3627
6/6
✓ Branch 0 taken 3008970 times.
✓ Branch 1 taken 34351920 times.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 3003860 times.
✓ Branch 4 taken 2626 times.
✓ Branch 5 taken 2484 times.
37360890 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3628 2484 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3629
3630 37358406 base_scr->ffcs[i].draw_ffc(bmp, x, y, (layer==-1));
3631 37358406 }
3632 186798379 }
3633 170792391 void _do_current_ffc_layer(BITMAP* bmp, int32_t layer)
3634 {
3635
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 170792391 times.
170792391 if(!show_ffcs) return;
3636 346163004 for_every_base_screen_in_region([&](mapscr* base_scr, unsigned int region_scr_x, unsigned int region_scr_y) {
3637 175370613 screen_handle_t handle = {base_scr, base_scr, base_scr->screen, 0};
3638 175370613 do_ffc_layer(bmp, layer, handle, 0, 0);
3639 175370613 });
3640 170792391 }
3641 74977987 void do_scrolling_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3642 {
3643 74977987 mapscr* scr = screen_handle.scr;
3644 74977987 mapscr* base_scr = screen_handle.base_scr;
3645
3646
4/4
✓ Branch 0 taken 60869135 times.
✓ Branch 1 taken 14108852 times.
✓ Branch 2 taken 14108852 times.
✓ Branch 3 taken 74977987 times.
74977987 if (type == -3 || type == -4)
3647 {
3648 28217704 y += playing_field_offset;
3649
3650
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
28217704 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3651 {
3652 if (base_scr->ffcs[i].data == 0)
3653 continue;
3654
3655 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3656 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3657
3658 base_scr->ffcs[i].draw_ffc(bmp, x, y, (type==-4));
3659 }
3660 return;
3661 }
3662
3663 74977987 x -= viewport.x;
3664 74977987 y -= viewport.y - playing_field_offset;
3665
3666 74977987 bool over = true, transp = false;
3667 74977987 int layer = screen_handle.layer;
3668
3669
7/8
✓ Branch 0 taken 54551896 times.
✓ Branch 1 taken 20426091 times.
✓ Branch 2 taken 13135475 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 33627289 times.
✓ Branch 5 taken 20924607 times.
✓ Branch 6 taken 3046783 times.
✓ Branch 7 taken 4243833 times.
74977987 switch(type ? type : layer)
3670 {
3671 case -2: //push blocks
3672
2/2
✓ Branch 0 taken 19518437 times.
✓ Branch 1 taken 14108852 times.
33627289 if (scr)
3673 {
3674
2/2
✓ Branch 0 taken 3435244912 times.
✓ Branch 1 taken 24303777 times.
3434329469 for(int32_t i=0; i<176; i++)
3675 {
3676 3435244912 int32_t mf=scr->sflag[i], mf2 = combobuf[scr->data[i]].flag;
3677
3678
10/10
✓ Branch 0 taken 3435074568 times.
✓ Branch 1 taken 170344 times.
✓ Branch 2 taken 3433602596 times.
✓ Branch 3 taken 1471972 times.
✓ Branch 4 taken 3432973613 times.
✓ Branch 5 taken 628983 times.
✓ Branch 6 taken 24420876 times.
✓ Branch 7 taken 3408552737 times.
✓ Branch 8 taken 42763031 times.
✓ Branch 9 taken 16297927 times.
3472292380 if(mf==mfPUSHUD || mf==mfPUSH4 || mf==mfPUSHED || ((mf>=mfPUSHLR)&&(mf<=mfPUSHRINS))
3679
6/8
✓ Branch 0 taken 3430092083 times.
✓ Branch 1 taken 21539346 times.
✓ Branch 2 taken 3430092083 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3430092083 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 37047468 times.
✓ Branch 7 taken 3393044615 times.
3432973613 || mf2==mfPUSHUD || mf2==mfPUSH4 || mf2==mfPUSHED || ((mf2>=mfPUSHLR)&&(mf2<=mfPUSHRINS)))
3680 {
3681
4/4
✓ Branch 0 taken 4772508 times.
✓ Branch 1 taken 695982 times.
✓ Branch 2 taken 3657 times.
✓ Branch 3 taken 4768851 times.
90994552 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3682 5468490 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3683 5468490 }
3684 3414811032 }
3685 24303777 }
3686 38412629 return;
3687
3688 case -1: //over combo
3689
1/2
✓ Branch 0 taken 20924607 times.
✗ Branch 1 not taken.
20924607 if (scr)
3690 {
3691
2/2
✓ Branch 0 taken 3682730832 times.
✓ Branch 1 taken 20924607 times.
3703655439 for(int32_t i=0; i<176; i++)
3692 {
3693
2/2
✓ Branch 0 taken 3663460684 times.
✓ Branch 1 taken 19270148 times.
3682730832 if(combo_class_buf[combobuf[scr->data[i]].type].overhead)
3694 {
3695
4/4
✓ Branch 0 taken 15517569 times.
✓ Branch 1 taken 3752579 times.
✓ Branch 2 taken 22320 times.
✓ Branch 3 taken 15495249 times.
19270148 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3696 19270148 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3697 19270148 }
3698 3682730832 }
3699 20924607 }
3700 20924607 return;
3701
3702 case 1:
3703 case 4:
3704 case 5:
3705 case 6:
3706
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13135475 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
13135475 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3707 {
3708
1/2
✓ Branch 0 taken 13135475 times.
✗ Branch 1 not taken.
13135475 if (scr)
3709 {
3710
2/2
✓ Branch 0 taken 11476264 times.
✓ Branch 1 taken 1659211 times.
13135475 if(base_scr->layeropacity[layer-1]!=255)
3711 1659211 transp = true;
3712 13135475 break;
3713 }
3714 }
3715 return;
3716
3717 case 2:
3718
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3046783 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3046783 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3719 {
3720
1/2
✓ Branch 0 taken 3046783 times.
✗ Branch 1 not taken.
3046783 if (scr)
3721 {
3722
2/2
✓ Branch 0 taken 2827186 times.
✓ Branch 1 taken 219597 times.
3046783 if(base_scr->layeropacity[layer-1]!=255)
3723 219597 transp = true;
3724
3725
2/2
✓ Branch 0 taken 2917873 times.
✓ Branch 1 taken 128910 times.
3046783 if(XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3726 128910 over = false;
3727
3728 3046783 break;
3729 }
3730 }
3731 return;
3732
3733 case 3:
3734
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4243833 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4243833 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3735 {
3736
1/2
✓ Branch 0 taken 4243833 times.
✗ Branch 1 not taken.
4243833 if (scr)
3737 {
3738
2/2
✓ Branch 0 taken 4170120 times.
✓ Branch 1 taken 73713 times.
4243833 if(base_scr->layeropacity[layer-1]!=255)
3739 73713 transp = true;
3740
3741
2/2
✓ Branch 0 taken 36655 times.
✓ Branch 1 taken 60483 times.
4243833 if(XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
3742
2/2
✓ Branch 0 taken 97138 times.
✓ Branch 1 taken 4146695 times.
4243833 && !XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3743 60483 over = false;
3744
3745 4243833 break;
3746 }
3747 }
3748 return;
3749 }
3750
3751 int start_x, end_x, start_y, end_y;
3752 20426091 get_bounds_for_draw_cmb_calls(bmp, x, y, start_x, end_x, start_y, end_y);
3753
2/2
✓ Branch 0 taken 20426091 times.
✓ Branch 1 taken 216559212 times.
236985303 for (int cy = start_y; cy < end_y; cy++)
3754 {
3755
2/2
✓ Branch 0 taken 3277111687 times.
✓ Branch 1 taken 216559212 times.
3493670899 for (int cx = start_x; cx < end_x; cx++)
3756 {
3757 3277111687 int i = cx + cy*16;
3758
4/4
✓ Branch 0 taken 2899406684 times.
✓ Branch 1 taken 377705003 times.
✓ Branch 2 taken 10227360 times.
✓ Branch 3 taken 2889179324 times.
3277111687 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3759 3277111687 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, over, transp);
3760 3277111687 }
3761 216559212 }
3762 60869135 }
3763
3764 268788105 bool lenscheck(mapscr* scr, int layer)
3765 {
3766
4/4
✓ Branch 0 taken 268609157 times.
✓ Branch 1 taken 178948 times.
✓ Branch 2 taken 178948 times.
✓ Branch 3 taken 268788105 times.
268788105 if(layer < 0 || layer > 6) return true;
3767
2/2
✓ Branch 0 taken 259565871 times.
✓ Branch 1 taken 9222234 times.
268788105 if(get_qr(qr_OLD_LENS_LAYEREFFECT))
3768 {
3769
2/2
✓ Branch 0 taken 209692261 times.
✓ Branch 1 taken 49873610 times.
259565871 if(!layer) return true;
3770
8/8
✓ Branch 0 taken 34919337 times.
✓ Branch 1 taken 174772924 times.
✓ Branch 2 taken 258970 times.
✓ Branch 3 taken 34660367 times.
✓ Branch 4 taken 143758 times.
✓ Branch 5 taken 163336 times.
✓ Branch 6 taken 326536 times.
✓ Branch 7 taken 34477589 times.
209692261 if((layer==(int32_t)(scr->lens_layer&7)+1) && ((scr->lens_layer&llLENSSHOWS && !lensclk) || (scr->lens_layer&llLENSHIDES && lensclk)))
3771 489872 return false;
3772 209250513 }
3773 else
3774 {
3775
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9222234 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9222234 times.
9222234 if((lensclk ? scr->lens_hide : scr->lens_show) & (1<<layer))
3776 return false;
3777 }
3778 218472747 return true;
3779 268609157 }
3780
3781 156023072 void do_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3782 {
3783 156023072 bool showlayer = true;
3784 156023072 mapscr* base_scr = screen_handle.base_scr;
3785 156023072 int layer = screen_handle.layer;
3786
2/2
✓ Branch 0 taken 42037754 times.
✓ Branch 1 taken 113985318 times.
156023072 int target = type ? type : layer;
3787
3/4
✓ Branch 0 taken 113985318 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20227475 times.
✓ Branch 3 taken 21810279 times.
156023072 switch(target)
3788 {
3789 case -2:
3790
1/2
✓ Branch 0 taken 20227475 times.
✗ Branch 1 not taken.
20227475 if(!show_layer_push)
3791 showlayer = false;
3792 20227475 break;
3793
3794 case -1:
3795
1/2
✓ Branch 0 taken 21810279 times.
✗ Branch 1 not taken.
21810279 if(!show_layer_over)
3796 showlayer = false;
3797 21810279 break;
3798
3799 case 1: case 2: case 3:
3800 case 4: case 5: case 6:
3801 113985318 showlayer = show_layers[target];
3802 113985318 break;
3803 }
3804
3805
2/2
✓ Branch 0 taken 42037754 times.
✓ Branch 1 taken 113985318 times.
156023072 if(!type)
3806 {
3807
2/2
✓ Branch 0 taken 113849120 times.
✓ Branch 1 taken 136198 times.
113985318 if(!lenscheck(base_scr,layer))
3808 136198 showlayer = false;
3809 113985318 }
3810
3811
2/2
✓ Branch 0 taken 136198 times.
✓ Branch 1 taken 155886874 times.
156023072 if(showlayer)
3812 {
3813
6/6
✓ Branch 0 taken 60925258 times.
✓ Branch 1 taken 94961616 times.
✓ Branch 2 taken 20482214 times.
✓ Branch 3 taken 40443044 times.
✓ Branch 4 taken 56123 times.
✓ Branch 5 taken 20426091 times.
155886874 if (screen_handle.scr && (type || !(base_scr->hidelayers & (1 << (layer)))))
3814 {
3815 60869135 do_scrolling_layer(bmp, type, screen_handle, x, y);
3816
4/4
✓ Branch 0 taken 20426091 times.
✓ Branch 1 taken 40443044 times.
✓ Branch 2 taken 19233766 times.
✓ Branch 3 taken 1192325 times.
60869135 if(!type && !get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
3817
2/2
✓ Branch 0 taken 1191749 times.
✓ Branch 1 taken 576 times.
1192901 if(mblock2.draw(bmp,layer))
3818 576 do_primitives(bmp, SPLAYER_MOVINGBLOCK);
3819 60869135 }
3820 155886874 }
3821 156023072 }
3822
3823 102941649 void do_layer_primitives(BITMAP *bmp, int32_t layer)
3824 {
3825 102941649 bool showlayer = true;
3826
3827
2/4
✓ Branch 0 taken 102941649 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 102941649 times.
102941649 if(layer >= 0 && layer <= 6)
3828 {
3829 102941649 showlayer = show_layers[layer];
3830
3831
2/2
✓ Branch 0 taken 102815047 times.
✓ Branch 1 taken 126602 times.
102941649 if(!lenscheck(origin_scr,layer))
3832 126602 showlayer = false;
3833 102941649 }
3834
3835
2/2
✓ Branch 0 taken 126602 times.
✓ Branch 1 taken 102815047 times.
102941649 if (showlayer)
3836 102815047 do_primitives(bmp, layer);
3837 102941649 }
3838
3839 // Called by do_walkflags
3840 void put_walkflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
3841 {
3842 newcombo const &c = combobuf[cmbdat];
3843
3844 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3845
3846 int32_t xx = x-xofs;
3847 int32_t yy = y+playing_field_offset-yofs;
3848
3849 int32_t bridgedetected = 0;
3850
3851 for(int32_t i=0; i<4; i++)
3852 {
3853 int32_t tx=((i&2)<<2)+xx - viewport.x;
3854 int32_t ty=((i&1)<<3)+yy - viewport.y;
3855 int32_t tx2=((i&2)<<2)+x - viewport.x;
3856 int32_t ty2=((i&1)<<3)+y - viewport.y;
3857 for (int32_t j = lyr-1; j <= 1; j++)
3858 {
3859 if (get_qr(qr_OLD_BRIDGE_COMBOS))
3860 {
3861 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && !_walkflag_layer(tx2,ty2,j))
3862 {
3863 bridgedetected |= (1<<i);
3864 }
3865 }
3866 else
3867 {
3868 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && _effectflag_layer(tx2,ty2,j))
3869 {
3870 bridgedetected |= (1<<i);
3871 }
3872 }
3873 }
3874 if ((bridgedetected & (1<<i)))
3875 {
3876 if (i >= 3) break;
3877 else continue;
3878 }
3879 bool doladdercheck = true;
3880
3881 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
3882 {
3883 for(int32_t k=0; k<8; k+=2)
3884 for(int32_t j=0; j<8; j+=2)
3885 if(((k+j)/2)%2)
3886 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,makecol(85,85,255));
3887 }
3888 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
3889 {
3890 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
3891 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
3892 rectfill(dest,tx,ty,tx+7,ty+7,makecol(85,85,255));
3893 else rectfill(dest,tx,ty,tx+7,ty+7,makecol(170,170,170));
3894 }
3895
3896 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
3897 {
3898 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
3899 {
3900 for(int32_t k=0; k<8; k+=2)
3901 for(int32_t j=0; j<8; j+=2)
3902 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,((k+j)/2)%2 ? makecol(165,105,8) : makecol(170,170,170));
3903 }
3904 else
3905 {
3906 int32_t color = makecol(178,36,36);
3907
3908 if(isstepable(cmbdat)&& (!doladdercheck))
3909 color=makecol(165,105,8);
3910 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
3911 color=makecol(170,170,170);
3912
3913 rectfill(dest,tx,ty,tx+7,ty+7,color);
3914 }
3915 }
3916 }
3917
3918 // Draw damage combos
3919 bool dmg = combo_class_buf[combobuf[MAPCOMBO2(-1,xx,yy)].type].modify_hp_amount
3920 || combo_class_buf[combobuf[MAPCOMBO2(0,xx,yy)].type].modify_hp_amount
3921 || combo_class_buf[combobuf[MAPCOMBO2(1,xx,yy)].type].modify_hp_amount;
3922
3923 if(dmg)
3924 {
3925 int32_t color = makecol(255,255,0);
3926 if (bridgedetected <= 0)
3927 {
3928 for(int32_t k=0; k<16; k+=2)
3929 for(int32_t j=0; j<16; j+=2)
3930 if(((k+j)/2)%2)
3931 {
3932 int32_t x0 = x - viewport.x;
3933 int32_t y0 = y - viewport.y;
3934 rectfill(dest,x0+k,y0+j,x0+k+1,y0+j+1,color);
3935 }
3936 }
3937 else
3938 {
3939 for(int32_t i=0; i<4; i++)
3940 {
3941 if (!(bridgedetected & (1<<i)))
3942 {
3943 int32_t tx=((i&2)<<2)+x - viewport.x;
3944 int32_t ty=((i&1)<<3)+y - viewport.y;
3945 for(int32_t k=0; k<8; k+=2)
3946 for(int32_t j=0; j<8; j+=2)
3947 if((k+j)%4 < 2) rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,color);
3948 }
3949 }
3950 }
3951 }
3952 }
3953 static void put_walkflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
3954 {
3955 ALLEGRO_COLOR col_solid = al_map_rgba(178,36,36,info_opacity);
3956 ALLEGRO_COLOR col_water1 = al_map_rgba(85,85,255,info_opacity);
3957 ALLEGRO_COLOR col_lhook = al_map_rgba(170,170,170,info_opacity);
3958 ALLEGRO_COLOR col_stepable = al_map_rgba(165,105,8,info_opacity);
3959 ALLEGRO_COLOR col_dmg = al_map_rgba(255,255,0,info_opacity);
3960 newcombo const &c = combobuf[cmbdat];
3961
3962 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3963
3964 int32_t xx = x-viewport.x;
3965 int32_t yy = y+playing_field_offset-viewport.y;
3966
3967 int32_t bridgedetected = 0;
3968
3969 // Draw damage combos
3970 bool dmg = combo_class_buf[c.type].modify_hp_amount;
3971
3972 for(int32_t i=0; i<4; i++)
3973 {
3974 int32_t tx=((i&2)<<2)+xx;
3975 int32_t ty=((i&1)<<3)+yy;
3976 int32_t tx2=((i&2)<<2)+x;
3977 int32_t ty2=((i&1)<<3)+y;
3978 for (int32_t m = lyr-1; m <= 1; m++)
3979 {
3980 if (get_qr(qr_OLD_BRIDGE_COMBOS))
3981 {
3982 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && !_walkflag_layer(tx2, ty2, m))
3983 {
3984 bridgedetected |= (1<<i);
3985 }
3986 }
3987 else
3988 {
3989 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && _effectflag_layer(tx2, ty2, m))
3990 {
3991 bridgedetected |= (1<<i);
3992 }
3993 }
3994 }
3995 if ((bridgedetected & (1<<i)))
3996 continue;
3997 bool doladdercheck = true;
3998
3999 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4000 {
4001 for(int32_t k=0; k<8; k+=2)
4002 for(int32_t j=0; j<8; j+=2)
4003 if(((k+j)/2)%2)
4004 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_water1);
4005 }
4006 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4007 {
4008 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4009 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4010 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_water1);
4011 else al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_lhook);
4012 }
4013
4014 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4015 {
4016 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4017 {
4018 for(int32_t k=0; k<8; k+=2)
4019 for(int32_t j=0; j<8; j+=2)
4020 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,((k+j)/2)%2 ? col_stepable : col_lhook);
4021 }
4022 else
4023 {
4024 ALLEGRO_COLOR* color = &col_solid;
4025
4026 if(isstepable(cmbdat)&& (!doladdercheck))
4027 color=&col_stepable;
4028 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4029 color=&col_lhook;
4030
4031 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,*color);
4032 }
4033 }
4034
4035 if(dmg)
4036 {
4037 for(int32_t k=0; k<8; k+=2)
4038 for(int32_t j=0; j<8; j+=2)
4039 if((k+j)%4 < 2) al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_dmg);
4040 }
4041 }
4042 }
4043
4044 void put_effectflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
4045 {
4046 newcombo const &c = combobuf[cmbdat];
4047
4048 int32_t xx = x-xofs-viewport.x;
4049 int32_t yy = y+playing_field_offset-yofs-viewport.y;
4050
4051 for(int32_t i=0; i<4; i++)
4052 {
4053 int32_t tx=((i&2)<<2)+xx;
4054 int32_t ty=((i&1)<<3)+yy;
4055
4056 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4057 {
4058 int32_t color = vc(10);
4059
4060 rectfill(dest,tx,ty,tx+7,ty+7,color);
4061 }
4062 }
4063 }
4064 static void put_effectflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4065 {
4066 ALLEGRO_COLOR col_eff = al_map_rgba(85,255,85,info_opacity);
4067 newcombo const &c = combobuf[cmbdat];
4068
4069 int32_t xx = x-viewport.x;
4070 int32_t yy = y+playing_field_offset-viewport.y;
4071
4072 for(int32_t i=0; i<4; i++)
4073 {
4074 int32_t tx=((i&2)<<2)+xx;
4075 int32_t ty=((i&1)<<3)+yy;
4076
4077 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4078 {
4079 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_eff);
4080 }
4081 }
4082 }
4083
4084 void draw_ladder_platform(BITMAP* dest, int32_t x, int32_t y, int32_t c)
4085 {
4086 for(auto cx = 0; cx < 256; cx += 16)
4087 {
4088 for(auto cy = 0; cy < 176; cy += 16)
4089 {
4090 if(isSVLadder(cx,cy))
4091 {
4092 auto nx = cx+x, ny = cy+y;
4093 if(cy && !isSVLadder(cx,cy-16))
4094 line(dest,nx,ny,nx+15,ny,c);
4095 rectfill(dest,nx,ny,nx+3,ny+15,c);
4096 rectfill(dest,nx+12,ny,nx+15,ny+15,c);
4097 rectfill(dest,nx+4,ny+2,nx+11,ny+5,c);
4098 rectfill(dest,nx+4,ny+10,nx+11,ny+13,c);
4099 }
4100 else if(isSVPlatform(cx,cy))
4101 {
4102 line(dest,cx+x,cy+y,cx+x+15,cy+y,c);
4103 }
4104 }
4105 }
4106 }
4107 void draw_ladder_platform_a5(int32_t x, int32_t y, ALLEGRO_COLOR c)
4108 {
4109 for(auto cx = 0; cx < 256; cx += 16)
4110 {
4111 for(auto cy = 0; cy < 176; cy += 16)
4112 {
4113 if(isSVLadder(cx,cy))
4114 {
4115 auto nx = cx+x, ny = cy+y;
4116 if(cy && !isSVLadder(cx,cy-16))
4117 al_draw_line(nx,ny,nx+15,ny,c,1);
4118 al_draw_filled_rectangle(nx,ny,nx+4,ny+16,c);
4119 al_draw_filled_rectangle(nx+12,ny,nx+16,ny+16,c);
4120 al_draw_filled_rectangle(nx+4,ny+2,nx+12,ny+6,c);
4121 al_draw_filled_rectangle(nx+4,ny+10,nx+12,ny+14,c);
4122 }
4123 else if(isSVPlatform(cx,cy))
4124 {
4125 al_draw_line(cx+x,cy+y,cx+x+15,cy+y,c,1);
4126 }
4127 }
4128 }
4129 }
4130
4131 // Walkflags L4 cheat
4132 void do_walkflags(const screen_handles_t& screen_handles, int32_t x, int32_t y)
4133 {
4134 if (!show_walkflags)
4135 return;
4136
4137 start_info_bmp();
4138
4139 mapscr* scr = screen_handles[0].scr;
4140 for(int32_t i=0; i<176; i++)
4141 {
4142 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4143 }
4144
4145 for(int32_t k=0; k<2; k++)
4146 {
4147 scr = screen_handles[k + 1].scr;
4148
4149 if (scr)
4150 {
4151 for(int32_t i=0; i<176; i++)
4152 {
4153 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], k%2+1);
4154 }
4155 }
4156 }
4157
4158 end_info_bmp();
4159 }
4160
4161 void do_walkflags(int32_t x, int32_t y)
4162 {
4163 if (!show_walkflags)
4164 return;
4165
4166 x += -viewport.x;
4167 y += playing_field_offset - viewport.y;
4168
4169 start_info_bmp();
4170
4171 draw_ladder_platform_a5(x,y,al_map_rgba(165,105,8,info_opacity));
4172 draw_solid_objects_a5(x,y,al_map_rgba(178,36,36,info_opacity));
4173 draw_slopes_a5(x,y,al_map_rgba(255,85,255,info_opacity));
4174
4175 end_info_bmp();
4176 }
4177
4178 // Effectflags L4 cheat
4179 void do_effectflags(mapscr* scr, int32_t x, int32_t y)
4180 {
4181 if(show_effectflags)
4182 {
4183 start_info_bmp();
4184
4185 for(int32_t i=0; i<176; i++)
4186 {
4187 put_effectflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4188 }
4189
4190 end_info_bmp();
4191 }
4192 }
4193
4194 272141 void calc_darkroom_combos(mapscr* scr, int offx, int offy)
4195 {
4196 272141 int map = scr->map;
4197 272141 int screen = scr->screen;
4198
4199
2/2
✓ Branch 0 taken 1904987 times.
✓ Branch 1 taken 272141 times.
2177128 for(int32_t lyr = 0; lyr < 7; ++lyr)
4200 {
4201 1904987 mapscr* scr = get_scr_layer(map, screen, lyr);
4202
2/2
✓ Branch 0 taken 780869 times.
✓ Branch 1 taken 1124118 times.
1904987 if (!scr->is_valid()) continue;
4203
4204
2/2
✓ Branch 0 taken 137432944 times.
✓ Branch 1 taken 780869 times.
138213813 for(int32_t q = 0; q < 176; ++q)
4205 {
4206 137432944 newcombo const& cmb = combobuf[scr->data[q]];
4207
2/2
✓ Branch 0 taken 136828325 times.
✓ Branch 1 taken 604619 times.
137432944 if(cmb.type == cTORCH)
4208 {
4209 604619 do_torch_combo(cmb, COMBOX(q)+8+offx, COMBOY(q)+8+offy, darkscr_bmp);
4210 604619 }
4211 137432944 }
4212 780869 }
4213 272141 }
4214
4215 272141 void calc_darkroom_ffcs(mapscr* scr, int offx, int offy)
4216 {
4217 272141 word c = scr->numFFC();
4218
2/2
✓ Branch 0 taken 537406 times.
✓ Branch 1 taken 272141 times.
809547 for(int q = 0; q < c; ++q)
4219 {
4220 537406 newcombo const& cmb = combobuf[scr->ffcs[q].data];
4221
2/2
✓ Branch 0 taken 522598 times.
✓ Branch 1 taken 14808 times.
537406 if(cmb.type == cTORCH)
4222 {
4223 14808 int cx = scr->ffcs[q].x.getInt()+(scr->ffEffectWidth(q)/2)+offx;
4224 14808 int cy = (scr->ffcs[q].y.getInt())+(scr->ffEffectHeight(q)/2)+offy;
4225 14808 do_torch_combo(cmb, cx, cy, darkscr_bmp);
4226 14808 }
4227 537406 }
4228 272141 }
4229
4230 struct nearby_screen_t
4231 {
4232 int screen;
4233 int offx;
4234 int offy;
4235 screen_handles_t screen_handles;
4236 };
4237 typedef std::vector<nearby_screen_t> nearby_screens_t;
4238
4239 15474627 static nearby_screens_t get_nearby_screens_non_scrolling_region()
4240 {
4241 15474627 nearby_screens_t nearby_screens;
4242
4243 15474627 mapscr* base_scr = origin_scr;
4244
1/2
✓ Branch 0 taken 15474627 times.
✗ Branch 1 not taken.
15474627 auto& nearby_screen = nearby_screens.emplace_back();
4245 15474627 nearby_screen.screen = cur_screen;
4246
1/2
✓ Branch 0 taken 15474627 times.
✗ Branch 1 not taken.
15474627 nearby_screen.screen_handles = create_screen_handles(base_scr);
4247
4248 15474627 return nearby_screens;
4249
1/2
✓ Branch 0 taken 15474627 times.
✗ Branch 1 not taken.
15474627 }
4250
4251 48296 static nearby_screens_t get_nearby_screens_scrolling_region()
4252 {
4253 48296 nearby_screens_t nearby_screens;
4254
4255
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x0 = viewport.left() / 256;
4256
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x1 = (viewport.right() - 1) / 256;
4257
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y0 = viewport.top() / 176;
4258
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y1 = (viewport.bottom() - 1) / 176;
4259
4260
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x0 = std::clamp(screens_x0, 0, 15);
4261
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x1 = std::clamp(screens_x1, 0, 15);
4262
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y0 = std::clamp(screens_y0, 0, 8);
4263
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y1 = std::clamp(screens_y1, 0, 8);
4264
4265
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 79928 times.
128224 for (int x = screens_x0; x <= screens_x1; x++)
4266 {
4267
2/2
✓ Branch 0 taken 169672 times.
✓ Branch 1 taken 79928 times.
249600 for (int y = screens_y0; y <= screens_y1; y++)
4268 {
4269 169672 int screen = cur_screen + x + y*16;
4270
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!is_in_current_region(screen)) continue;
4271
4272
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 mapscr* base_scr = get_scr(screen);
4273
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!base_scr->is_valid()) continue;
4274
4275
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
4276
4277
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto& nearby_screen = nearby_screens.emplace_back();
4278 169672 nearby_screen.screen = screen;
4279 169672 nearby_screen.offx = offx;
4280 169672 nearby_screen.offy = offy;
4281
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 nearby_screen.screen_handles = create_screen_handles(base_scr);
4282 169672 }
4283 79928 }
4284
4285 48296 return nearby_screens;
4286
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 }
4287
4288 3658 static nearby_screens_t get_nearby_screens_smooth_maze()
4289 {
4290 3658 nearby_screens_t nearby_screens;
4291
4292
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x0 = viewport.left() / 256;
4293
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x1 = (viewport.right() - 1) / 256;
4294
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y0 = viewport.top() / 176;
4295
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y1 = (viewport.bottom() - 1) / 176;
4296
4297
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.left() < 0) screens_x0--;
4298
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.top() < 0) screens_y0--;
4299
4300
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 7308 times.
10966 for (int x = screens_x0; x <= screens_x1; x++)
4301 {
4302
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 7308 times.
25908 for (int y = screens_y0; y <= screens_y1; y++)
4303 {
4304 18600 int screen = -1;
4305 mapscr* base_scr;
4306 int offx, offy;
4307
4308 18600 mapscr* maze_scr = maze_state.scr;
4309 18600 int maze_screen = maze_scr->screen;
4310
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_x = get_region_relative_dx(maze_screen);
4311
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_y = get_region_relative_dy(maze_screen);
4312 18600 int maze_screen_dx = x - maze_screen_x;
4313 18600 int maze_screen_dy = y - maze_screen_y;
4314 18600 int exitdir = maze_scr->exitdir;
4315
4316 bool should_draw_maze_screen;
4317
2/2
✓ Branch 0 taken 9052 times.
✓ Branch 1 taken 9548 times.
18600 if (maze_state.lost)
4318 {
4319 9548 should_draw_maze_screen = true;
4320 9548 }
4321 else
4322 {
4323 9052 should_draw_maze_screen = true;
4324
4/6
✓ Branch 0 taken 9052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6844 times.
✓ Branch 3 taken 2208 times.
✓ Branch 4 taken 6844 times.
✗ Branch 5 not taken.
9052 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != exitdir && XY_DELTA_TO_DIR(0, maze_screen_dy) != exitdir;
4325
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 5202 times.
9052 if (maze_state.enter_dir != dir_invalid)
4326
4/6
✓ Branch 0 taken 3850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3304 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 3304 times.
✗ Branch 5 not taken.
3850 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != maze_state.enter_dir && XY_DELTA_TO_DIR(0, maze_screen_dy) != maze_state.enter_dir;
4327 }
4328
4329
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (should_draw_maze_screen)
4330 {
4331 16048 screen = maze_state.scr->screen;
4332 16048 base_scr = maze_state.scr;
4333
1/2
✓ Branch 0 taken 16048 times.
✗ Branch 1 not taken.
16048 std::tie(offx, offy) = translate_screen_coordinates_to_world(cur_screen + x + y*16);
4334 16048 }
4335
4336
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (screen == -1)
4337 {
4338 2552 screen = cur_screen + x + y*16;
4339
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!is_in_current_region(screen)) continue;
4340
4341
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 base_scr = get_scr(screen);
4342
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!base_scr->is_valid()) continue;
4343
4344
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 std::tie(offx, offy) = translate_screen_coordinates_to_world(screen);
4345 2552 }
4346
4347
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 auto& nearby_screen = nearby_screens.emplace_back();
4348 18600 nearby_screen.screen = screen;
4349 18600 nearby_screen.offx = offx;
4350 18600 nearby_screen.offy = offy;
4351
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 nearby_screen.screen_handles = create_screen_handles(base_scr);
4352 18600 }
4353 7308 }
4354
4355 3658 return nearby_screens;
4356
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 }
4357
4358 15526581 static nearby_screens_t get_nearby_screens()
4359 {
4360
4/4
✓ Branch 0 taken 9214 times.
✓ Branch 1 taken 15517367 times.
✓ Branch 2 taken 3658 times.
✓ Branch 3 taken 5556 times.
15526581 if (maze_state.active && maze_state.loopy)
4361 3658 return get_nearby_screens_smooth_maze();
4362
4363
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 15474627 times.
15522923 if (is_in_scrolling_region())
4364 48296 return get_nearby_screens_scrolling_region();
4365
4366 15474627 return get_nearby_screens_non_scrolling_region();
4367 15526581 }
4368
4369 201878713 static void for_every_nearby_screen(const nearby_screens_t& nearby_screens, const std::function <void (screen_handles_t, int, int, int)>& fn)
4370 {
4371
2/2
✓ Branch 0 taken 203663315 times.
✓ Branch 1 taken 201878713 times.
405542028 for (auto& nearby_screen : nearby_screens)
4372 203663315 fn(nearby_screen.screen_handles, nearby_screen.screen, nearby_screen.offx, nearby_screen.offy);
4373 201878713 }
4374
4375 124212648 static void draw_msgstr(byte layer, BITMAP* dest = nullptr)
4376 {
4377
2/2
✓ Branch 0 taken 15526581 times.
✓ Branch 1 taken 108686067 times.
124212648 if(layer != msgstr_layer) return;
4378
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 if(!dest) dest = framebuf;
4379
4380
2/2
✓ Branch 0 taken 679040 times.
✓ Branch 1 taken 14847541 times.
15526581 if(!(msg_bg_display_buf->clip))
4381 {
4382 679040 blit_msgstr_bg(dest,0,0,0,playing_field_offset,256,176);
4383 679040 }
4384
4385
2/2
✓ Branch 0 taken 679040 times.
✓ Branch 1 taken 14847541 times.
15526581 if(!(msg_portrait_display_buf->clip))
4386 {
4387 679040 blit_msgstr_prt(dest,0,0,0,playing_field_offset,256,176);
4388 679040 }
4389
4390
2/2
✓ Branch 0 taken 692447 times.
✓ Branch 1 taken 14834134 times.
15526581 if(!(msg_txt_display_buf->clip))
4391 {
4392 692447 blit_msgstr_fg(dest,0,0,0,playing_field_offset,256,176);
4393 692447 }
4394 124212648 }
4395
4396 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y);
4397
4398 62106324 static void set_draw_screen_clip(BITMAP* bmp)
4399 {
4400 62106324 set_clip_rect(bmp, draw_screen_clip_rect_x1, draw_screen_clip_rect_y1, draw_screen_clip_rect_x2, draw_screen_clip_rect_y2);
4401 62106324 }
4402
4403 46082339 void draw_screen(bool showhero, bool runGeneric)
4404 {
4405 46082339 clear_info_bmp();
4406
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46082339 times.
46082339 if((GameFlags & (GAMEFLAG_SCRIPTMENU_ACTIVE|GAMEFLAG_F6SCRIPT_ACTIVE))!=0)
4407 {
4408 FFCore.doScriptMenuDraws();
4409 return;
4410 }
4411
4412
2/2
✓ Branch 0 taken 31156412 times.
✓ Branch 1 taken 14925927 times.
46082339 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_PRE_DRAW);
4413
4414 46082339 clear_bitmap(framebuf);
4415 46082339 clear_clip_rect(framebuf);
4416
4417 46082339 int32_t cmby2=0;
4418
4419 // Draw some background layers
4420 46082339 clear_bitmap(scrollbuf);
4421
4422 46082339 auto nearby_screens = get_nearby_screens();
4423
4424 // Handle layer 2/3 possibly being background layers.
4425
1/2
✓ Branch 0 taken 46082339 times.
✗ Branch 1 not taken.
61745238 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4426 15662899 mapscr* base_scr = screen_handles[0].base_scr;
4427
2/2
✓ Branch 0 taken 15535617 times.
✓ Branch 1 taken 127282 times.
15662899 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4428 127282 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4429 15662899 });
4430
4431
2/2
✓ Branch 0 taken 127282 times.
✓ Branch 1 taken 45955057 times.
46082339 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4432 {
4433
1/2
✓ Branch 0 taken 127282 times.
✗ Branch 1 not taken.
127282 do_layer_primitives(scrollbuf, 2);
4434
1/2
✓ Branch 0 taken 127282 times.
✗ Branch 1 not taken.
127282 particles.draw(scrollbuf, true, 2);
4435 127282 }
4436
2/2
✓ Branch 0 taken 15526581 times.
✓ Branch 1 taken 30555758 times.
46082339 _do_current_ffc_layer(scrollbuf, -2);
4437
2/2
✓ Branch 0 taken 127282 times.
✓ Branch 1 taken 15399299 times.
15526581 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4438
1/2
✓ Branch 0 taken 127282 times.
✗ Branch 1 not taken.
127282 draw_msgstr(2, scrollbuf);
4439
4440
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4441 15662899 mapscr* base_scr = screen_handles[0].base_scr;
4442
2/2
✓ Branch 0 taken 15570239 times.
✓ Branch 1 taken 92660 times.
15662899 if (XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4443 92660 do_layer(scrollbuf, 0, screen_handles[3], offx, offy);
4444 15662899 });
4445
4446
2/2
✓ Branch 0 taken 92660 times.
✓ Branch 1 taken 15433921 times.
15526581 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4447 {
4448
1/2
✓ Branch 0 taken 92660 times.
✗ Branch 1 not taken.
92660 do_layer_primitives(scrollbuf, 3);
4449
1/2
✓ Branch 0 taken 92660 times.
✗ Branch 1 not taken.
92660 particles.draw(scrollbuf, true, 3);
4450 92660 }
4451
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(scrollbuf, -3);
4452
2/2
✓ Branch 0 taken 92660 times.
✓ Branch 1 taken 15433921 times.
15526581 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4453
1/2
✓ Branch 0 taken 92660 times.
✗ Branch 1 not taken.
92660 draw_msgstr(3, scrollbuf);
4454
4455 // Draw the main combo screens ("layer 0").
4456
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4457 15662899 mapscr* base_scr = screen_handles[0].base_scr;
4458
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15662899 times.
15662899 if (lenscheck(base_scr, 0))
4459 {
4460 15662899 putscr(base_scr, scrollbuf, offx, offy + playing_field_offset);
4461 15662899 }
4462 15662899 });
4463
4464
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15526581 times.
15526581 if (lenscheck(hero_scr, 0))
4465 {
4466
2/2
✓ Branch 0 taken 454382 times.
✓ Branch 1 taken 15072199 times.
15526581 if(!get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4467
3/4
✓ Branch 0 taken 454382 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4136 times.
✓ Branch 3 taken 450246 times.
458518 if(mblock2.draw(scrollbuf,0))
4468
1/2
✓ Branch 0 taken 4136 times.
✗ Branch 1 not taken.
4136 do_primitives(scrollbuf, SPLAYER_MOVINGBLOCK);
4469 15526581 }
4470
4471 // Lens hints, then primitives, then particles.
4472
6/10
✓ Branch 0 taken 15516552 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15516552 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15516552 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5876 times.
✓ Branch 9 taken 4153 times.
15526581 if((lensclk || (get_debug() && zc_getkey(KEY_L))) && !get_qr(qr_OLDLENSORDER))
4473 {
4474
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 draw_lens_under(scrollbuf, false);
4475
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4476 5876 }
4477
4478
2/4
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15526581 times.
✗ Branch 3 not taken.
15526581 if(show_layers[0] && lenscheck(hero_scr,0))
4479
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_primitives(scrollbuf, 0);
4480
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 particles.draw(scrollbuf, true, 0);
4481
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(scrollbuf, 0);
4482
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 draw_msgstr(0, scrollbuf);
4483
4484
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 set_draw_screen_clip(scrollbuf);
4485
4486
2/2
✓ Branch 0 taken 15183322 times.
✓ Branch 1 taken 343259 times.
15526581 if(!(get_qr(qr_LAYER12UNDERCAVE)))
4487 {
4488
4/4
✓ Branch 0 taken 15181448 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 15093064 times.
30330018 if(showhero &&
4489
4/6
✓ Branch 0 taken 15181448 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15146696 times.
✓ Branch 3 taken 34752 times.
✓ Branch 4 taken 15146696 times.
✗ Branch 5 not taken.
15181448 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4490 {
4491
3/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 34752 times.
88384 if(Hero.getAction()==climbcovertop)
4492 {
4493 34752 cmby2=16;
4494 34752 }
4495
2/4
✓ Branch 0 taken 53632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53632 times.
53632 else if(Hero.getAction()==climbcoverbottom)
4496 {
4497 53632 cmby2=-16;
4498 53632 }
4499
4500
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw2(scrollbuf,true);
4501
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 Hero.draw(scrollbuf);
4502
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw(scrollbuf,true);
4503
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccx = (int32_t)Hero.getClimbCoverX();
4504
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccy = (int32_t)Hero.getClimbCoverY();
4505
4506
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4507
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4508
4509
4/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✓ Branch 5 taken 73152 times.
88384 if(int32_t(Hero.getX())&15)
4510 {
4511
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4512
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4513 15232 }
4514 88384 }
4515 15183322 }
4516
4517
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4518 15662899 do_layer(scrollbuf, 0, screen_handles[1], offx, offy); // LAYER 1
4519 15662899 });
4520
4521
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_layer_primitives(scrollbuf, 1);
4522
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 particles.draw(scrollbuf, true, 1);
4523
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(scrollbuf, 1);
4524
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 draw_msgstr(1, scrollbuf);
4525
4526 // Handle layer 2 NOT being used as background layers.
4527
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4528 15662899 mapscr* base_scr = screen_handles[0].base_scr;
4529
2/2
✓ Branch 0 taken 127282 times.
✓ Branch 1 taken 15535617 times.
15662899 if (!XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4530 15535617 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4531 15662899 });
4532
4533
2/2
✓ Branch 0 taken 15399299 times.
✓ Branch 1 taken 127282 times.
15526581 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4534 {
4535
1/2
✓ Branch 0 taken 15399299 times.
✗ Branch 1 not taken.
15399299 do_layer_primitives(scrollbuf, 2);
4536
1/2
✓ Branch 0 taken 15399299 times.
✗ Branch 1 not taken.
15399299 particles.draw(scrollbuf, true, 2);
4537 15399299 }
4538
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(scrollbuf, 2);
4539
2/2
✓ Branch 0 taken 15399299 times.
✓ Branch 1 taken 127282 times.
15526581 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4540
1/2
✓ Branch 0 taken 15399299 times.
✗ Branch 1 not taken.
15399299 draw_msgstr(2, scrollbuf);
4541
4542
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_primitives(scrollbuf, SPLAYER_FFC_DRAW);
4543
4544
2/2
✓ Branch 0 taken 343259 times.
✓ Branch 1 taken 15183322 times.
15526581 if(get_qr(qr_LAYER12UNDERCAVE))
4545 {
4546
2/4
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 343259 times.
686518 if(showhero &&
4547
3/6
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 343259 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 343259 times.
✗ Branch 5 not taken.
343259 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4548 {
4549 if(Hero.getAction()==climbcovertop)
4550 {
4551 cmby2=16;
4552 }
4553 else if(Hero.getAction()==climbcoverbottom)
4554 {
4555 cmby2=-16;
4556 }
4557
4558 decorations.draw2(scrollbuf,true);
4559 Hero.draw(scrollbuf);
4560 decorations.draw(scrollbuf,true);
4561 int32_t ccx = (int32_t)(Hero.getClimbCoverX());
4562 int32_t ccy = (int32_t)(Hero.getClimbCoverY());
4563
4564 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4565 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4566
4567 if(int32_t(Hero.getX())&15)
4568 {
4569 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4570 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4571 }
4572 }
4573 343259 }
4574
4575
2/2
✓ Branch 0 taken 454382 times.
✓ Branch 1 taken 15072199 times.
15526581 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4576 {
4577
1/2
✓ Branch 0 taken 15072199 times.
✗ Branch 1 not taken.
30280716 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4578 15208517 do_layer(scrollbuf, -2, screen_handles[0], offx, offy); // push blocks!
4579
2/2
✓ Branch 0 taken 14478396 times.
✓ Branch 1 taken 730121 times.
15208517 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
4580 {
4581 730121 do_layer(scrollbuf, -2, screen_handles[1], offx, offy); // push blocks!
4582 730121 do_layer(scrollbuf, -2, screen_handles[2], offx, offy); // push blocks!
4583 730121 }
4584 15208517 });
4585
4586
1/2
✓ Branch 0 taken 15072199 times.
✗ Branch 1 not taken.
15072199 do_primitives(scrollbuf, SPLAYER_PUSHBLOCK);
4587 15072199 }
4588
4589 // Show walkflags cheat
4590
2/4
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15526581 times.
15526581 if (show_walkflags || show_effectflags)
4591 {
4592 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4593 do_walkflags(screen_handles, offx, offy);
4594 do_effectflags(screen_handles[0].base_scr, offx, offy);
4595 });
4596
4597 do_walkflags(0, 0);
4598 }
4599
4600
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 putscrdoors(nearby_screens, scrollbuf, 0, playing_field_offset);
4601
4602 // Lens hints, doors etc.
4603
4/8
✓ Branch 0 taken 15516552 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15516552 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15516552 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
15526581 if(lensclk || (get_debug() && zc_getkey(KEY_L)))
4604 {
4605
2/2
✓ Branch 0 taken 4153 times.
✓ Branch 1 taken 5876 times.
10029 if(get_qr(qr_OLDLENSORDER))
4606 {
4607
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 draw_lens_under(scrollbuf, false);
4608
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4609 4153 }
4610
4611
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 draw_lens_under(scrollbuf, true);
4612
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_2);
4613 10029 }
4614
4615 // Blit those layers onto framebuf
4616
4617
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 set_draw_screen_clip(framebuf);
4618
4619
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 blit(scrollbuf, framebuf, 0, 0, 0, 0, 256, 232);
4620
4621 // After this point, scrollbuf is no longer drawn to - so things like dosubscr have access to a "partially rendered" frame.
4622 // I think only used for COOLSCROLL==0? Seems like a silly feature...
4623
4624 // Draw the subscreen, without clipping
4625
2/2
✓ Branch 0 taken 9250859 times.
✓ Branch 1 taken 6275722 times.
15526581 if(!get_qr(qr_SUBSCREENOVERSPRITES))
4626 {
4627 9250859 bool dotime = false;
4628
4/6
✓ Branch 0 taken 9250859 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3412328 times.
✓ Branch 3 taken 5838531 times.
✓ Branch 4 taken 3412328 times.
✗ Branch 5 not taken.
9250859 if (replay_version_check(22)) dotime = game->should_show_time();
4629
1/2
✓ Branch 0 taken 9250859 times.
✗ Branch 1 not taken.
9250859 put_passive_subscr(framebuf, 0, 0, dotime, sspUP);
4630 9250859 }
4631
4632 // Draw some sprites onto framebuf
4633
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 set_clip_rect(framebuf,0,0,256,232);
4634
4635
2/2
✓ Branch 0 taken 99496 times.
✓ Branch 1 taken 15427085 times.
15526581 if(!(pricesdisplaybuf->clip))
4636 {
4637
1/2
✓ Branch 0 taken 99496 times.
✗ Branch 1 not taken.
99496 masked_blit(pricesdisplaybuf,framebuf,0,0,0,playing_field_offset,256,176);
4638 99496 }
4639
4640
5/6
✓ Branch 0 taken 15480955 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15474627 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15526581 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4641 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4642
4643
8/10
✓ Branch 0 taken 15524707 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 15524707 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15489955 times.
✓ Branch 5 taken 34752 times.
✓ Branch 6 taken 15489955 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15436323 times.
✓ Branch 9 taken 53632 times.
15526581 if(showhero && ((Hero.getAction()!=climbcovertop)&&(Hero.getAction()!=climbcoverbottom)))
4644 {
4645
1/2
✓ Branch 0 taken 15436323 times.
✗ Branch 1 not taken.
15436323 Hero.draw_under(framebuf);
4646
4647
3/4
✓ Branch 0 taken 15436323 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141385 times.
✓ Branch 3 taken 15294938 times.
15436323 if(Hero.isSwimming())
4648 {
4649
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw2(framebuf,true);
4650
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 Hero.draw(framebuf);
4651
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw(framebuf,true);
4652 141385 }
4653 15436323 }
4654
4655
2/2
✓ Branch 0 taken 26095 times.
✓ Branch 1 taken 15500486 times.
15526581 if(drawguys)
4656 {
4657
4/4
✓ Branch 0 taken 1982149 times.
✓ Branch 1 taken 13518337 times.
✓ Branch 2 taken 990826 times.
✓ Branch 3 taken 991323 times.
15500486 if(get_qr(qr_NOFLICKER) || (frame&1))
4658 {
4659 // Just clips sprites if in a repeating, smooth maze.
4660
2/2
✓ Branch 0 taken 14499949 times.
✓ Branch 1 taken 9214 times.
14509163 bool do_clip = maze_state.active && maze_state.loopy;
4661
4662
3/4
✓ Branch 0 taken 23609261 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9100098 times.
✓ Branch 3 taken 14509163 times.
23609261 for(int32_t i=0; i<Ewpns.Count(); i++)
4663 {
4664
3/4
✓ Branch 0 taken 9100098 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✓ Branch 3 taken 8902155 times.
9100098 if(((weapon *)Ewpns.spr(i))->behind)
4665
2/4
✓ Branch 0 taken 197943 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✗ Branch 3 not taken.
197943 Ewpns.spr(i)->draw(framebuf);
4666 9100098 }
4667
1/2
✓ Branch 0 taken 14509163 times.
✗ Branch 1 not taken.
14509163 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4668
4669
3/4
✓ Branch 0 taken 19183147 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4673984 times.
✓ Branch 3 taken 14509163 times.
19183147 for(int32_t i=0; i<Lwpns.Count(); i++)
4670 {
4671
3/4
✓ Branch 0 taken 4673984 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✓ Branch 3 taken 4670779 times.
4673984 if(((weapon *)Lwpns.spr(i))->behind)
4672
2/4
✓ Branch 0 taken 3205 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✗ Branch 3 not taken.
3205 Lwpns.spr(i)->draw(framebuf);
4673 4673984 }
4674
1/2
✓ Branch 0 taken 14509163 times.
✗ Branch 1 not taken.
14509163 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4675
4676
6/6
✓ Branch 0 taken 9772562 times.
✓ Branch 1 taken 4736601 times.
✓ Branch 2 taken 1348300 times.
✓ Branch 3 taken 8424262 times.
✓ Branch 4 taken 674011 times.
✓ Branch 5 taken 674289 times.
14509163 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4677 {
4678
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 9094615 times.
9098273 if (do_clip)
4679
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.drawshadow_smooth_maze(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4680 else
4681
1/2
✓ Branch 0 taken 9094615 times.
✗ Branch 1 not taken.
9094615 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4682 9098273 }
4683
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14505505 times.
14509163 if (do_clip)
4684
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.draw_smooth_maze(framebuf);
4685 else
4686
1/2
✓ Branch 0 taken 14505505 times.
✗ Branch 1 not taken.
14505505 guys.draw(framebuf,true);
4687
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14505505 times.
14509163 if (do_clip)
4688 {
4689 3658 int maze_screen = maze_state.scr->screen;
4690
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4691
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4692 3658 }
4693
1/2
✓ Branch 0 taken 14509163 times.
✗ Branch 1 not taken.
14509163 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4694
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14505505 times.
14509163 if (do_clip)
4695
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4696
4697
1/2
✓ Branch 0 taken 14509163 times.
✗ Branch 1 not taken.
14509163 chainlinks.draw(framebuf,true);
4698
1/2
✓ Branch 0 taken 14509163 times.
✗ Branch 1 not taken.
14509163 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4699 //Lwpns.draw(framebuf,true);
4700
4701
3/4
✓ Branch 0 taken 23609261 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9100098 times.
✓ Branch 3 taken 14509163 times.
23609261 for(int32_t i=0; i<Ewpns.Count(); i++)
4702 {
4703
3/4
✓ Branch 0 taken 9100098 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8902155 times.
✓ Branch 3 taken 197943 times.
9100098 if(!((weapon *)Ewpns.spr(i))->behind)
4704
2/4
✓ Branch 0 taken 8902155 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8902155 times.
✗ Branch 3 not taken.
8902155 Ewpns.spr(i)->draw(framebuf);
4705 9100098 }
4706
1/2
✓ Branch 0 taken 14509163 times.
✗ Branch 1 not taken.
14509163 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4707
4708
3/4
✓ Branch 0 taken 19183147 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4673984 times.
✓ Branch 3 taken 14509163 times.
19183147 for(int32_t i=0; i<Lwpns.Count(); i++)
4709 {
4710
3/4
✓ Branch 0 taken 4673984 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4670779 times.
✓ Branch 3 taken 3205 times.
4673984 if(!((weapon *)Lwpns.spr(i))->behind)
4711
2/4
✓ Branch 0 taken 4670779 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4670779 times.
✗ Branch 3 not taken.
4670779 Lwpns.spr(i)->draw(framebuf);
4712 4673984 }
4713
1/2
✓ Branch 0 taken 14509163 times.
✗ Branch 1 not taken.
14509163 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4714
4715
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14505505 times.
14509163 if (do_clip)
4716
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 items.draw_smooth_maze(framebuf);
4717 else
4718
1/2
✓ Branch 0 taken 14505505 times.
✗ Branch 1 not taken.
14505505 items.draw(framebuf,true);
4719
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14505505 times.
14509163 if (do_clip)
4720 {
4721 3658 int maze_screen = maze_state.scr->screen;
4722
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4723
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4724 3658 }
4725
1/2
✓ Branch 0 taken 14509163 times.
✗ Branch 1 not taken.
14509163 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4726
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14505505 times.
14509163 if (do_clip)
4727
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4728 14509163 }
4729 else
4730 {
4731
3/4
✓ Branch 0 taken 1496695 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991323 times.
1496695 for(int32_t i=0; i<Ewpns.Count(); i++)
4732 {
4733
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✓ Branch 3 taken 496727 times.
505372 if(((weapon *)Ewpns.spr(i))->behind)
4734
2/4
✓ Branch 0 taken 8645 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
8645 Ewpns.spr(i)->draw(framebuf);
4735 505372 }
4736
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4737
4738
3/4
✓ Branch 0 taken 1222321 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 230998 times.
✓ Branch 3 taken 991323 times.
1222321 for(int32_t i=0; i<Lwpns.Count(); i++)
4739 {
4740
2/4
✓ Branch 0 taken 230998 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 230998 times.
230998 if(((weapon *)Lwpns.spr(i))->behind)
4741 Lwpns.spr(i)->draw(framebuf);
4742 230998 }
4743
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4744
4745
3/4
✓ Branch 0 taken 228620 times.
✓ Branch 1 taken 762703 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228620 times.
991323 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4746 {
4747
1/2
✓ Branch 0 taken 228620 times.
✗ Branch 1 not taken.
228620 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4748 228620 }
4749
4750
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 items.draw(framebuf,false);
4751
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4752
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 chainlinks.draw(framebuf,false);
4753
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4754 //Lwpns.draw(framebuf,false);
4755
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 guys.draw(framebuf,false);
4756
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4757
4758
3/4
✓ Branch 0 taken 1496695 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991323 times.
1496695 for(int32_t i=0; i<Ewpns.Count(); i++)
4759 {
4760
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✓ Branch 3 taken 8645 times.
505372 if(!((weapon *)Ewpns.spr(i))->behind)
4761 {
4762
2/4
✓ Branch 0 taken 496727 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✗ Branch 3 not taken.
496727 Ewpns.spr(i)->draw(framebuf);
4763 496727 }
4764 505372 }
4765
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4766
4767
3/4
✓ Branch 0 taken 1222321 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 230998 times.
✓ Branch 3 taken 991323 times.
1222321 for(int32_t i=0; i<Lwpns.Count(); i++)
4768 {
4769
2/4
✓ Branch 0 taken 230998 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 230998 times.
✗ Branch 3 not taken.
230998 if(!((weapon *)Lwpns.spr(i))->behind)
4770 {
4771
2/4
✓ Branch 0 taken 230998 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 230998 times.
✗ Branch 3 not taken.
230998 Lwpns.spr(i)->draw(framebuf);
4772 230998 }
4773 230998 }
4774
1/2
✓ Branch 0 taken 991323 times.
✗ Branch 1 not taken.
991323 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4775 }
4776
4777
1/2
✓ Branch 0 taken 15500486 times.
✗ Branch 1 not taken.
15500486 guys.draw2(framebuf,true);
4778 15500486 }
4779
4780
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15526581 times.
15526581 if(mirror_portal.destdmap > -1)
4781 mirror_portal.draw(framebuf);
4782
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 portals.draw(framebuf,true);
4783
4784
8/10
✓ Branch 0 taken 15524707 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 15524707 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15489955 times.
✓ Branch 5 taken 34752 times.
✓ Branch 6 taken 15489955 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15436323 times.
✓ Branch 9 taken 53632 times.
15526581 if(showhero && ((Hero.getAction()!=climbcovertop)&& (Hero.getAction()!=climbcoverbottom)))
4785 {
4786
2/2
✓ Branch 0 taken 14988357 times.
✓ Branch 1 taken 447966 times.
15436323 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4787 {
4788
1/2
✓ Branch 0 taken 14988357 times.
✗ Branch 1 not taken.
14988357 mblock2.draw(framebuf,-1);
4789
1/2
✓ Branch 0 taken 14988357 times.
✗ Branch 1 not taken.
14988357 do_primitives(framebuf, SPLAYER_MOVINGBLOCK);
4790 14988357 }
4791
3/4
✓ Branch 0 taken 15436323 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15294938 times.
✓ Branch 3 taken 141385 times.
15436323 if(!Hero.isSwimming())
4792 {
4793
8/12
✓ Branch 0 taken 15294938 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15294938 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15277194 times.
✓ Branch 5 taken 17744 times.
✓ Branch 6 taken 15277194 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15277194 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1370 times.
✓ Branch 11 taken 15293568 times.
15294938 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4794 {
4795
2/2
✓ Branch 0 taken 17059 times.
✓ Branch 1 taken 15277879 times.
15294938 Hero.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4796 17059 }
4797
4798
6/8
✓ Branch 0 taken 15294938 times.
✓ Branch 1 taken 15277879 times.
✓ Branch 2 taken 15294938 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15294938 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15281853 times.
✓ Branch 7 taken 13085 times.
17059 if(Hero.getZ() <= (zfix)zinit.jump_hero_layer_threshold)
4799 {
4800
1/2
✓ Branch 0 taken 15281853 times.
✗ Branch 1 not taken.
15281853 decorations.draw2(framebuf,true);
4801
1/2
✓ Branch 0 taken 15281853 times.
✗ Branch 1 not taken.
15281853 Hero.draw(framebuf);
4802
1/2
✓ Branch 0 taken 15281853 times.
✗ Branch 1 not taken.
15281853 decorations.draw(framebuf,true);
4803 15281853 }
4804 15294938 }
4805 15436323 }
4806
4807
3/4
✓ Branch 0 taken 54864043 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39337462 times.
✓ Branch 3 taken 15526581 times.
54864043 for(int32_t i=0; i<guys.Count(); i++)
4808 {
4809
3/4
✓ Branch 0 taken 39337462 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15942473 times.
✓ Branch 3 taken 23394989 times.
39337462 if(((enemy*)guys.spr(i))->family == eeWALK)
4810 {
4811
3/4
✓ Branch 0 taken 15942473 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✓ Branch 3 taken 15935178 times.
15942473 if(((eStalfos*)guys.spr(i))->hashero)
4812 {
4813
2/4
✓ Branch 0 taken 7295 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✗ Branch 3 not taken.
7295 guys.spr(i)->draw(framebuf);
4814 7295 }
4815 15942473 }
4816
4817
3/4
✓ Branch 0 taken 39337462 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 507162 times.
✓ Branch 3 taken 38830300 times.
39337462 if(((enemy*)guys.spr(i))->family == eeWALLM)
4818 {
4819
3/4
✓ Branch 0 taken 507162 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✓ Branch 3 taken 505833 times.
507162 if(((eWallM*)guys.spr(i))->hashero)
4820 {
4821
2/4
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
1329 guys.spr(i)->draw(framebuf);
4822 1329 }
4823 507162 }
4824
4825
11/20
✓ Branch 0 taken 39337462 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39337462 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39337462 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 39337462 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 39337462 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 39337462 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 39337462 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 39337462 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 39337462 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1342694 times.
✓ Branch 19 taken 37994768 times.
39337462 if(guys.spr(i)->z+guys.spr(i)->fakez > Hero.getZ()+Hero.getFakeZ())
4826 {
4827 //Jumping enemies in front of Hero.
4828
2/4
✓ Branch 0 taken 1342694 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1342694 times.
✗ Branch 3 not taken.
1342694 guys.spr(i)->draw(framebuf);
4829 1342694 }
4830
1/2
✓ Branch 0 taken 39337462 times.
✗ Branch 1 not taken.
39337462 do_primitives(framebuf, SPLAYER_NPC_ABOVEPLAYER_DRAW);
4831 39337462 }
4832
4833 // Draw some layers onto framebuf
4834
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 set_draw_screen_clip(framebuf);
4835
5/6
✓ Branch 0 taken 15480955 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15474627 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15526581 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4836 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4837
4838 // Handle layer 3 NOT being used as background layers.
4839
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4840 15662899 mapscr* base_scr = screen_handles[0].base_scr;
4841
2/2
✓ Branch 0 taken 92660 times.
✓ Branch 1 taken 15570239 times.
15662899 if (!XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4842 15570239 do_layer(framebuf, 0, screen_handles[3], offx, offy);
4843 15662899 });
4844
4845
2/2
✓ Branch 0 taken 15433921 times.
✓ Branch 1 taken 92660 times.
15526581 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4846 {
4847
1/2
✓ Branch 0 taken 15433921 times.
✗ Branch 1 not taken.
15433921 do_layer_primitives(framebuf, 3);
4848
1/2
✓ Branch 0 taken 15433921 times.
✗ Branch 1 not taken.
15433921 particles.draw(framebuf, true, 3);
4849 15433921 }
4850
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(framebuf, 3);
4851
2/2
✓ Branch 0 taken 15433921 times.
✓ Branch 1 taken 92660 times.
15526581 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4852
1/2
✓ Branch 0 taken 15433921 times.
✗ Branch 1 not taken.
15433921 draw_msgstr(3);
4853
4854
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4855 15662899 do_layer(framebuf, 0, screen_handles[4], offx, offy);
4856 15662899 });
4857
4858
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_layer_primitives(framebuf, 4);
4859
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 particles.draw(framebuf, true, 4);
4860
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(framebuf, 4);
4861
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 draw_msgstr(4);
4862
4863
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4864 15662899 do_layer(framebuf, -1, screen_handles[0], offx, offy);
4865
2/2
✓ Branch 0 taken 14399676 times.
✓ Branch 1 taken 1263223 times.
15662899 if (get_qr(qr_OVERHEAD_COMBOS_L1_L2))
4866 {
4867 1263223 do_layer(framebuf, -1, screen_handles[1], offx, offy);
4868 1263223 do_layer(framebuf, -1, screen_handles[2], offx, offy);
4869 1263223 }
4870 15662899 });
4871
4872
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_primitives(framebuf, SPLAYER_OVERHEAD_CMB);
4873
4874 // Draw some flying sprites onto framebuf
4875
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 clear_clip_rect(framebuf);
4876
5/6
✓ Branch 0 taken 15480955 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15474627 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15526581 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4877 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4878
4879 //Jumping Hero and jumping enemies are drawn on this layer.
4880
5/8
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15526581 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15526581 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13085 times.
✓ Branch 7 taken 15513496 times.
15526581 if(Hero.getZ() > (zfix)zinit.jump_hero_layer_threshold)
4881 {
4882
1/2
✓ Branch 0 taken 13085 times.
✗ Branch 1 not taken.
13085 decorations.draw2(framebuf,false);
4883
1/2
✓ Branch 0 taken 13085 times.
✗ Branch 1 not taken.
13085 Hero.draw(framebuf);
4884
1/2
✓ Branch 0 taken 13085 times.
✗ Branch 1 not taken.
13085 chainlinks.draw(framebuf,true);
4885
1/2
✓ Branch 0 taken 13085 times.
✗ Branch 1 not taken.
13085 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4886
4887
3/4
✓ Branch 0 taken 15827 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✓ Branch 3 taken 13085 times.
15827 for(int32_t i=0; i<Lwpns.Count(); i++)
4888 {
4889
9/16
✓ Branch 0 taken 2742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2742 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2742 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2742 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2742 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 239 times.
✓ Branch 15 taken 2503 times.
2742 if(Lwpns.spr(i)->z+Lwpns.spr(i)->fakez > (zfix)zinit.jump_hero_layer_threshold)
4890 {
4891
2/4
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 Lwpns.spr(i)->draw(framebuf);
4892 239 }
4893 2742 }
4894
1/2
✓ Branch 0 taken 13085 times.
✗ Branch 1 not taken.
13085 do_primitives(framebuf, SPLAYER_LWEAP_ABOVE_DRAW);
4895
4896
1/2
✓ Branch 0 taken 13085 times.
✗ Branch 1 not taken.
13085 decorations.draw(framebuf,false);
4897 13085 }
4898
4899
5/6
✓ Branch 0 taken 3288982 times.
✓ Branch 1 taken 12237599 times.
✓ Branch 2 taken 44318199 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32080600 times.
✓ Branch 5 taken 12237599 times.
47607181 if(!get_qr(qr_ENEMIESZAXIS)) for(int32_t i=0; i<guys.Count(); i++)
4900 {
4901
13/22
✓ Branch 0 taken 32080600 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32080600 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27174502 times.
✓ Branch 5 taken 4906098 times.
✓ Branch 6 taken 27174502 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27174502 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27174502 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27174502 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27174502 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27174502 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27174502 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6568 times.
✓ Branch 21 taken 27167934 times.
32080600 if((isflier(guys.spr(i)->id)) || (guys.spr(i)->z+guys.spr(i)->fakez) > (zfix)zinit.jump_hero_layer_threshold)
4902 {
4903
2/4
✓ Branch 0 taken 4912666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4912666 times.
✗ Branch 3 not taken.
4912666 guys.spr(i)->draw(framebuf);
4904 4912666 }
4905 44318199 }
4906 else
4907 {
4908
3/4
✓ Branch 0 taken 10545844 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✓ Branch 3 taken 3288982 times.
10545844 for(int32_t i=0; i<guys.Count(); i++)
4909 {
4910
13/22
✓ Branch 0 taken 7256862 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6081157 times.
✓ Branch 5 taken 1175705 times.
✓ Branch 6 taken 6081157 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6081157 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6081157 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 5594346 times.
✓ Branch 13 taken 486811 times.
✓ Branch 14 taken 5594346 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 5594346 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 5594346 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 5594346 times.
7256862 if((isflier(guys.spr(i)->id)) || guys.spr(i)->z > 0 || guys.spr(i)->fakez > 0)
4911 {
4912
2/4
✓ Branch 0 taken 1662516 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1662516 times.
✗ Branch 3 not taken.
1662516 guys.spr(i)->draw(framebuf);
4913 1662516 }
4914 7256862 }
4915 }
4916
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_primitives(framebuf, SPLAYER_NPC_AIRBORNE_DRAW);
4917
4918 // Draw the Moving Fairy above layer 3
4919
3/4
✓ Branch 0 taken 18668452 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3141871 times.
✓ Branch 3 taken 15526581 times.
18668452 for(int32_t i=0; i<items.Count(); i++)
4920
6/8
✓ Branch 0 taken 3141871 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69867 times.
✓ Branch 3 taken 3072004 times.
✓ Branch 4 taken 69867 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60153 times.
✓ Branch 7 taken 9714 times.
3202024 if(itemsbuf[items.spr(i)->id].family == itype_fairy && itemsbuf[items.spr(i)->id].misc3)
4921
2/4
✓ Branch 0 taken 60153 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60153 times.
✗ Branch 3 not taken.
60153 items.spr(i)->draw(framebuf);
4922
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_primitives(framebuf, SPLAYER_FAIRYITEM_DRAW);
4923
4924 // Draw some layers onto framebuf
4925
4926
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 set_draw_screen_clip(framebuf);
4927
4928
2/2
✓ Branch 0 taken 15512229 times.
✓ Branch 1 taken 14352 times.
15526581 if (lightbeam_present)
4929 {
4930 14352 color_map = &trans_table2;
4931
2/2
✓ Branch 0 taken 13114 times.
✓ Branch 1 taken 1238 times.
14352 if(get_qr(qr_LIGHTBEAM_TRANSPARENT))
4932
1/2
✓ Branch 0 taken 13114 times.
✗ Branch 1 not taken.
13114 draw_trans_sprite(framebuf, lightbeam_bmp, 0, playing_field_offset);
4933 else
4934
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 masked_blit(lightbeam_bmp, framebuf, 0, 0, 0, playing_field_offset, 256, 176);
4935 14352 color_map = &trans_table;
4936 14352 }
4937
4938
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4939 15662899 do_layer(framebuf, 0, screen_handles[5], offx, offy);
4940 15662899 });
4941
4942
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_layer_primitives(framebuf, 5);
4943
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 particles.draw(framebuf, true, 5);
4944
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(framebuf, 5);
4945
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 draw_msgstr(5);
4946
4947
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(framebuf, -1); // 'overhead' freeform combos
4948
4949
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_primitives(framebuf, SPLAYER_OVERHEAD_FFC);
4950
4951
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4952 15662899 do_layer(framebuf, 0, screen_handles[6], offx, offy);
4953 15662899 });
4954
4955
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 do_layer_primitives(framebuf, 6);
4956
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 particles.draw(framebuf, true, 6);
4957
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(framebuf, 6);
4958
4959 15526581 bool any_dark = false;
4960
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4961 15662899 mapscr* base_scr = screen_handles[0].scr;
4962 15662899 any_dark |= is_dark(base_scr);
4963 15662899 });
4964
4965 // Handle low drawn darkness
4966
4/4
✓ Branch 0 taken 1256887 times.
✓ Branch 1 taken 14269694 times.
✓ Branch 2 taken 1013116 times.
✓ Branch 3 taken 243771 times.
15526581 if(get_qr(qr_NEW_DARKROOM) && any_dark)
4967 {
4968
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4969 250005 mapscr* base_scr = screen_handles[0].scr;
4970 250005 calc_darkroom_combos(base_scr, offx, offy + playing_field_offset);
4971 250005 calc_darkroom_ffcs(base_scr, 0, playing_field_offset);
4972 250005 });
4973
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 if(showhero)
4974
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 Hero.calc_darkroom_hero(0, -playing_field_offset);
4975
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 243771 times.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4976 250005 mapscr* base_scr = screen_handles[0].scr;
4977
2/2
✓ Branch 0 taken 245275 times.
✓ Branch 1 taken 4730 times.
250005 if (!is_dark(base_scr))
4978 {
4979 4730 offy += playing_field_offset;
4980 4730 rectfill(darkscr_bmp, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
4981 4730 rectfill(darkscr_bmp_trans, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
4982 4730 }
4983 250005 });
4984 243771 }
4985
4986 //Darkroom if under the subscreen
4987
6/6
✓ Branch 0 taken 1256887 times.
✓ Branch 1 taken 14269694 times.
✓ Branch 2 taken 823284 times.
✓ Branch 3 taken 433603 times.
✓ Branch 4 taken 231780 times.
✓ Branch 5 taken 591504 times.
15526581 if(get_qr(qr_NEW_DARKROOM) && get_qr(qr_NEWDARK_L6) && any_dark)
4988 {
4989
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
4990
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4991
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231780 times.
231780 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
4992 {
4993 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
4994 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
4995 }
4996
4997 231780 color_map = &trans_table2;
4998
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 231636 times.
231780 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
4999 {
5000
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5001
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5002
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5003 144 }
5004 else
5005 {
5006
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5007
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5008 }
5009 231780 color_map = &trans_table;
5010
5011
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5012
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5013 231780 }
5014
5015
3/6
✓ Branch 0 taken 45626 times.
✓ Branch 1 taken 15480955 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45626 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
15526581 if (is_extended_height_mode() && lensclk && !FFCore.system_suspend[susptLENS])
5016 {
5017 draw_lens_over();
5018 --lensclk;
5019 }
5020
5021 // Draw some text on framebuf
5022
5023
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 set_clip_rect(framebuf,0,0,256,232);
5024
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 if(!get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5025
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 draw_msgstr(6);
5026
5027 // Draw the subscreen, without clipping
5028
2/2
✓ Branch 0 taken 6275722 times.
✓ Branch 1 taken 9250859 times.
15526581 if(get_qr(qr_SUBSCREENOVERSPRITES))
5029 {
5030
2/4
✓ Branch 0 taken 6275722 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6275722 times.
✗ Branch 3 not taken.
6275722 put_passive_subscr(framebuf, 0, 0, game->should_show_time(), sspUP);
5031
5032 // Draw primitives over subscren
5033
1/2
✓ Branch 0 taken 6275722 times.
✗ Branch 1 not taken.
6275722 do_primitives(framebuf, 7); //Layer '7' appears above subscreen if quest rule is set
5034 6275722 }
5035
5036
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15526581 times.
15526581 if(get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5037 draw_msgstr(6);
5038
5039 // Handle high-drawn darkness
5040
6/6
✓ Branch 0 taken 1256887 times.
✓ Branch 1 taken 14269694 times.
✓ Branch 2 taken 433603 times.
✓ Branch 3 taken 823284 times.
✓ Branch 4 taken 11991 times.
✓ Branch 5 taken 421612 times.
15526581 if(get_qr(qr_NEW_DARKROOM) && !get_qr(qr_NEWDARK_L6) && any_dark)
5041 {
5042
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5043
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5044
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5045 {
5046 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5047 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5048 }
5049
5050 11991 color_map = &trans_table2;
5051
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5052 {
5053 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5054 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5055 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5056 }
5057 else
5058 {
5059
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5060
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5061 }
5062 11991 color_map = &trans_table;
5063
5064
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5065
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5066 11991 }
5067
5068
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 _do_current_ffc_layer(framebuf, 7);
5069
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 draw_msgstr(7);
5070
5071
1/2
✓ Branch 0 taken 15526581 times.
✗ Branch 1 not taken.
15526581 set_clip_rect(scrollbuf, 0, 0, scrollbuf->w, scrollbuf->h);
5072
3/4
✓ Branch 0 taken 14925927 times.
✓ Branch 1 taken 600654 times.
✓ Branch 2 taken 14925927 times.
✗ Branch 3 not taken.
15526581 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_POST_DRAW);
5073 76638097 }
5074
5075 // TODO: separate setting door data and drawing door
5076 28152 void put_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t type, bool redraw, bool even_walls)
5077 {
5078
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28152 times.
28152 if (type > 8) return;
5079
5080 28152 int32_t d=scr->door_combo_set;
5081
5082
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15611 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12541 times.
28152 switch(type)
5083 {
5084 case dt_wall:
5085 case dt_walk:
5086 if(!even_walls)
5087 break;
5088 [[fallthrough]];
5089 case dt_pass:
5090
3/4
✓ Branch 0 taken 1035 times.
✓ Branch 1 taken 11506 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1035 times.
12541 if(!get_qr(qr_REPLACEOPENDOORS) && !even_walls)
5091 1035 break;
5092 [[fallthrough]];
5093 case dt_lock:
5094 case dt_shut:
5095 case dt_boss:
5096 case dt_olck:
5097 case dt_osht:
5098 case dt_obos:
5099 case dt_bomb:
5100
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7259 times.
✓ Branch 2 taken 6784 times.
✓ Branch 3 taken 6362 times.
✓ Branch 4 taken 6712 times.
27117 switch(side)
5101 {
5102 case up:
5103 7259 scr->data[pos] = DoorComboSets[d].doorcombo_u[type][0];
5104 7259 scr->cset[pos] = DoorComboSets[d].doorcset_u[type][0];
5105 7259 scr->sflag[pos] = 0;
5106 7259 scr->data[pos+1] = DoorComboSets[d].doorcombo_u[type][1];
5107 7259 scr->cset[pos+1] = DoorComboSets[d].doorcset_u[type][1];
5108 7259 scr->sflag[pos+1] = 0;
5109 7259 scr->data[pos+16] = DoorComboSets[d].doorcombo_u[type][2];
5110 7259 scr->cset[pos+16] = DoorComboSets[d].doorcset_u[type][2];
5111 7259 scr->sflag[pos+16] = 0;
5112 7259 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_u[type][3];
5113 7259 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_u[type][3];
5114 7259 scr->sflag[pos+16+1] = 0;
5115
5116
2/2
✓ Branch 0 taken 5435 times.
✓ Branch 1 taken 1824 times.
7259 if(redraw)
5117 {
5118 3648 putcombo(dest,(pos&15)<<4,pos&0xF0,
5119 1824 DoorComboSets[d].doorcombo_u[type][0],
5120 1824 DoorComboSets[d].doorcset_u[type][0]);
5121 3648 putcombo(dest,((pos&15)<<4)+16,pos&0xF0,
5122 1824 DoorComboSets[d].doorcombo_u[type][1],
5123 1824 DoorComboSets[d].doorcset_u[type][1]);
5124 1824 }
5125
5126 7259 break;
5127
5128 case down:
5129 6784 scr->data[pos] = DoorComboSets[d].doorcombo_d[type][0];
5130 6784 scr->cset[pos] = DoorComboSets[d].doorcset_d[type][0];
5131 6784 scr->sflag[pos] = 0;
5132 6784 scr->data[pos+1] = DoorComboSets[d].doorcombo_d[type][1];
5133 6784 scr->cset[pos+1] = DoorComboSets[d].doorcset_d[type][1];
5134 6784 scr->sflag[pos+1] = 0;
5135 6784 scr->data[pos+16] = DoorComboSets[d].doorcombo_d[type][2];
5136 6784 scr->cset[pos+16] = DoorComboSets[d].doorcset_d[type][2];
5137 6784 scr->sflag[pos+16] = 0;
5138 6784 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_d[type][3];
5139 6784 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_d[type][3];
5140 6784 scr->sflag[pos+16+1] = 0;
5141
5142
2/2
✓ Branch 0 taken 5463 times.
✓ Branch 1 taken 1321 times.
6784 if(redraw)
5143 {
5144 2642 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5145 1321 DoorComboSets[d].doorcombo_d[type][2],
5146 1321 DoorComboSets[d].doorcset_d[type][2]);
5147 2642 putcombo(dest,((pos&15)<<4)+16,(pos&0xF0)+16,
5148 1321 DoorComboSets[d].doorcombo_d[type][3],
5149 1321 DoorComboSets[d].doorcset_d[type][3]);
5150 1321 }
5151
5152 6784 break;
5153
5154 case left:
5155 6362 scr->data[pos] = DoorComboSets[d].doorcombo_l[type][0];
5156 6362 scr->cset[pos] = DoorComboSets[d].doorcset_l[type][0];
5157 6362 scr->sflag[pos] = 0;
5158 6362 scr->data[pos+1] = DoorComboSets[d].doorcombo_l[type][1];
5159 6362 scr->cset[pos+1] = DoorComboSets[d].doorcset_l[type][1];
5160 6362 scr->sflag[pos+1] = 0;
5161 6362 scr->data[pos+16] = DoorComboSets[d].doorcombo_l[type][2];
5162 6362 scr->cset[pos+16] = DoorComboSets[d].doorcset_l[type][2];
5163 6362 scr->sflag[pos+16] = 0;
5164 6362 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_l[type][3];
5165 6362 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_l[type][3];
5166 6362 scr->sflag[pos+16+1] = 0;
5167 6362 scr->data[pos+32] = DoorComboSets[d].doorcombo_l[type][4];
5168 6362 scr->cset[pos+32] = DoorComboSets[d].doorcset_l[type][4];
5169 6362 scr->sflag[pos+32] = 0;
5170 6362 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_l[type][5];
5171 6362 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_l[type][5];
5172 6362 scr->sflag[pos+32+1] = 0;
5173
5174
2/2
✓ Branch 0 taken 4873 times.
✓ Branch 1 taken 1489 times.
6362 if(redraw)
5175 {
5176 2978 putcombo(dest,(pos&15)<<4,pos&0xF0,
5177 1489 DoorComboSets[d].doorcombo_l[type][0],
5178 1489 DoorComboSets[d].doorcset_l[type][0]);
5179 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5180 1489 DoorComboSets[d].doorcombo_l[type][2],
5181 1489 DoorComboSets[d].doorcset_l[type][2]);
5182 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5183 1489 DoorComboSets[d].doorcombo_l[type][4],
5184 1489 DoorComboSets[d].doorcset_l[type][4]);
5185 1489 }
5186
5187 6362 break;
5188
5189 case right:
5190 6712 scr->data[pos] = DoorComboSets[d].doorcombo_r[type][0];
5191 6712 scr->cset[pos] = DoorComboSets[d].doorcset_r[type][0];
5192 6712 scr->sflag[pos] = 0;
5193 6712 scr->data[pos+1] = DoorComboSets[d].doorcombo_r[type][1];
5194 6712 scr->cset[pos+1] = DoorComboSets[d].doorcset_r[type][1];
5195 6712 scr->sflag[pos+1] = 0;
5196 6712 scr->data[pos+16] = DoorComboSets[d].doorcombo_r[type][2];
5197 6712 scr->cset[pos+16] = DoorComboSets[d].doorcset_r[type][2];
5198 6712 scr->sflag[pos+16] = 0;
5199 6712 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_r[type][3];
5200 6712 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_r[type][3];
5201 6712 scr->sflag[pos+16+1] = 0;
5202 6712 scr->data[pos+32] = DoorComboSets[d].doorcombo_r[type][4];
5203 6712 scr->cset[pos+32] = DoorComboSets[d].doorcset_r[type][4];
5204 6712 scr->sflag[pos+32] = 0;
5205 6712 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_r[type][5];
5206 6712 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_r[type][5];
5207 6712 scr->sflag[pos+32+1] = 0;
5208
5209
2/2
✓ Branch 0 taken 5058 times.
✓ Branch 1 taken 1654 times.
6712 if(redraw)
5210 {
5211 3308 putcombo(dest,(pos&15)<<4,pos&0xF0,
5212 1654 DoorComboSets[d].doorcombo_r[type][0],
5213 1654 DoorComboSets[d].doorcset_r[type][0]);
5214 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5215 1654 DoorComboSets[d].doorcombo_r[type][2],
5216 1654 DoorComboSets[d].doorcset_r[type][2]);
5217 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5218 1654 DoorComboSets[d].doorcombo_r[type][4],
5219 1654 DoorComboSets[d].doorcset_r[type][4]);
5220 1654 }
5221
5222 6712 break;
5223 }
5224
5225 27117 break;
5226
5227 default:
5228 break;
5229 }
5230 28152 }
5231
5232 706556 static void over_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t offx, int32_t offy)
5233 {
5234 706556 int32_t door_combo_set = scr->door_combo_set;
5235 706556 int32_t x = (pos&15)<<4;
5236 706556 int32_t y = (pos&0xF0);
5237 706556 int32_t d = door_combo_set;
5238 706556 x += offx;
5239 706556 y += offy;
5240
5241
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 161136 times.
✓ Branch 2 taken 179643 times.
✓ Branch 3 taken 196353 times.
✓ Branch 4 taken 169424 times.
706556 switch(side)
5242 {
5243 case up:
5244 322272 overcombo2(dest,x,y,
5245 161136 DoorComboSets[d].bombdoorcombo_u[0],
5246 161136 DoorComboSets[d].bombdoorcset_u[0]);
5247 322272 overcombo2(dest,x+16,y,
5248 161136 DoorComboSets[d].bombdoorcombo_u[1],
5249 161136 DoorComboSets[d].bombdoorcset_u[1]);
5250 161136 break;
5251
5252 case down:
5253 359286 overcombo2(dest,x,y,
5254 179643 DoorComboSets[d].bombdoorcombo_d[0],
5255 179643 DoorComboSets[d].bombdoorcset_d[0]);
5256 359286 overcombo2(dest,x+16,y,
5257 179643 DoorComboSets[d].bombdoorcombo_d[1],
5258 179643 DoorComboSets[d].bombdoorcset_d[1]);
5259 179643 break;
5260
5261 case left:
5262 392706 overcombo2(dest,x,y,
5263 196353 DoorComboSets[d].bombdoorcombo_l[0],
5264 196353 DoorComboSets[d].bombdoorcset_l[0]);
5265 392706 overcombo2(dest,x,y+16,
5266 196353 DoorComboSets[d].bombdoorcombo_l[1],
5267 196353 DoorComboSets[d].bombdoorcset_l[1]);
5268 392706 overcombo2(dest,x,y+16,
5269 196353 DoorComboSets[d].bombdoorcombo_l[2],
5270 196353 DoorComboSets[d].bombdoorcset_l[2]);
5271 196353 break;
5272
5273 case right:
5274 338848 overcombo2(dest,x,y,
5275 169424 DoorComboSets[d].bombdoorcombo_r[0],
5276 169424 DoorComboSets[d].bombdoorcset_r[0]);
5277 338848 overcombo2(dest,x,y+16,
5278 169424 DoorComboSets[d].bombdoorcombo_r[1],
5279 169424 DoorComboSets[d].bombdoorcset_r[1]);
5280 338848 overcombo2(dest,x,y+16,
5281 169424 DoorComboSets[d].bombdoorcombo_r[2],
5282 169424 DoorComboSets[d].bombdoorcset_r[2]);
5283 169424 break;
5284 }
5285 706556 }
5286
5287 47564 void update_door(mapscr* scr, int32_t side, int32_t door, bool even_walls)
5288 {
5289
7/8
✓ Branch 0 taken 47456 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 47456 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22924 times.
✓ Branch 5 taken 24532 times.
✓ Branch 6 taken 530 times.
✓ Branch 7 taken 22394 times.
47564 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5290 25170 return;
5291
5292 int32_t doortype;
5293
5294
10/12
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 655 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12491 times.
✓ Branch 5 taken 910 times.
✓ Branch 6 taken 1553 times.
✓ Branch 7 taken 3192 times.
✓ Branch 8 taken 1694 times.
✓ Branch 9 taken 172 times.
✓ Branch 10 taken 67 times.
✓ Branch 11 taken 1138 times.
22394 switch(door)
5295 {
5296 case dWALL:
5297 doortype=dt_wall;
5298 break;
5299
5300 case dWALK:
5301 doortype=dt_walk;
5302 break;
5303
5304 case dOPEN:
5305 12491 doortype=dt_pass;
5306 12491 break;
5307
5308 case dLOCKED:
5309 910 doortype=dt_lock;
5310 910 break;
5311
5312 case dUNLOCKED:
5313 1553 doortype=dt_olck;
5314 1553 break;
5315
5316 case dSHUTTER:
5317
3/4
✓ Branch 0 taken 2783 times.
✓ Branch 1 taken 409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2783 times.
3192 if(screenscrolling && ((HeroDir()^1)==side))
5318 {
5319 doortype=dt_osht;
5320 get_screen_state(scr->screen).open_doors = -4;
5321 break;
5322 }
5323
5324 [[fallthrough]];
5325 case d1WAYSHUTTER:
5326 3714 doortype=dt_shut;
5327 3714 break;
5328
5329 case dOPENSHUTTER:
5330 1694 doortype=dt_osht;
5331 1694 break;
5332
5333 case dBOSS:
5334 172 doortype=dt_boss;
5335 172 break;
5336
5337 case dOPENBOSS:
5338 67 doortype=dt_obos;
5339 67 break;
5340
5341 case dBOMBED:
5342 1138 doortype=dt_bomb;
5343 1138 break;
5344
5345 default:
5346 655 return;
5347 }
5348
5349
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5629 times.
✓ Branch 2 taken 5770 times.
✓ Branch 3 taken 5110 times.
✓ Branch 4 taken 5230 times.
21739 switch(side)
5350 {
5351 case up:
5352 5629 put_door(scr,nullptr,7,side,doortype,false,even_walls);
5353 5629 break;
5354
5355 case down:
5356 5770 put_door(scr,nullptr,151,side,doortype,false,even_walls);
5357 5770 break;
5358
5359 case left:
5360 5110 put_door(scr,nullptr,64,side,doortype,false,even_walls);
5361 5110 break;
5362
5363 case right:
5364 5230 put_door(scr,nullptr,78,side,doortype,false,even_walls);
5365 5230 break;
5366 }
5367 47564 }
5368
5369 6504 void putdoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t door, bool redraw, bool even_walls)
5370 {
5371 /*
5372 #define dWALL 0 // 000 0
5373 #define dBOMB 6 // 011 0
5374 #define 8 // 100 0
5375 enum {dt_pass=0, dt_lock, dt_shut, dt_boss, dt_olck, dt_osht, dt_obos, dt_wall, dt_bomb, dt_walk, dt_max};
5376 */
5377
5378
7/8
✓ Branch 0 taken 6504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6500 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6417 times.
✓ Branch 5 taken 83 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 6409 times.
6504 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5379 91 return;
5380
5381 int32_t doortype;
5382
5383
8/12
✓ Branch 0 taken 227 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 362 times.
✓ Branch 7 taken 1530 times.
✓ Branch 8 taken 3958 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 51 times.
✓ Branch 11 taken 231 times.
6413 switch(door)
5384 {
5385 case dWALL:
5386 doortype=dt_wall;
5387 break;
5388
5389 case dWALK:
5390 doortype=dt_walk;
5391 break;
5392
5393 case dOPEN:
5394 50 doortype=dt_pass;
5395 50 break;
5396
5397 case dLOCKED:
5398 doortype=dt_lock;
5399 break;
5400
5401 case dUNLOCKED:
5402 362 doortype=dt_olck;
5403 362 break;
5404
5405 case dSHUTTER:
5406
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1530 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1530 if(screenscrolling && ((HeroDir()^1)==side))
5407 {
5408 doortype=dt_osht;
5409 get_screen_state(cur_screen).open_doors = -4;
5410 break;
5411 }
5412
5413 [[fallthrough]];
5414 case d1WAYSHUTTER:
5415 1757 doortype=dt_shut;
5416 1757 break;
5417
5418 case dOPENSHUTTER:
5419 3958 doortype=dt_osht;
5420 3958 break;
5421
5422 case dBOSS:
5423 4 doortype=dt_boss;
5424 4 break;
5425
5426 case dOPENBOSS:
5427 51 doortype=dt_obos;
5428 51 break;
5429
5430 case dBOMBED:
5431 231 doortype=dt_bomb;
5432 231 break;
5433
5434 default:
5435 return;
5436 }
5437
5438
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1860 times.
✓ Branch 2 taken 1357 times.
✓ Branch 3 taken 1514 times.
✓ Branch 4 taken 1682 times.
6413 switch(side)
5439 {
5440 case up:
5441
2/2
✓ Branch 0 taken 1791 times.
✓ Branch 1 taken 69 times.
1860 switch(door)
5442 {
5443 case dBOMBED:
5444
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
138 if(redraw)
5445 {
5446 69 over_door(scr,dest,39,side,0,0);
5447 69 }
5448 [[fallthrough]];
5449 default:
5450 1860 put_door(scr,dest,7,side,doortype,redraw, even_walls);
5451 1860 break;
5452 }
5453
5454 1860 break;
5455
5456 case down:
5457
2/2
✓ Branch 0 taken 1318 times.
✓ Branch 1 taken 39 times.
1357 switch(door)
5458 {
5459 case dBOMBED:
5460
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if(redraw)
5461 {
5462 39 over_door(scr,dest,135,side,0,0);
5463 39 }
5464 [[fallthrough]];
5465 default:
5466 1357 put_door(scr,dest,151,side,doortype,redraw, even_walls);
5467 1357 break;
5468 }
5469
5470 1357 break;
5471
5472 case left:
5473
2/2
✓ Branch 0 taken 1463 times.
✓ Branch 1 taken 51 times.
1514 switch(door)
5474 {
5475 case dBOMBED:
5476
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 if(redraw)
5477 {
5478 51 over_door(scr,dest,66,side,0,0);
5479 51 }
5480 [[fallthrough]];
5481 default:
5482 1514 put_door(scr,dest,64,side,doortype,redraw, even_walls);
5483 1514 break;
5484 }
5485
5486 1514 break;
5487
5488 case right:
5489
2/2
✓ Branch 0 taken 1610 times.
✓ Branch 1 taken 72 times.
1682 switch(door)
5490 {
5491 case dBOMBED:
5492
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
144 if(redraw)
5493 {
5494 72 over_door(scr,dest,77,side,0,0);
5495 72 }
5496 [[fallthrough]];
5497 default:
5498 1682 put_door(scr,dest,78,side,doortype,redraw, even_walls);
5499 1682 break;
5500 }
5501
5502 1682 break;
5503 }
5504 6504 }
5505
5506 586 void putcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5507 {
5508
1/2
✓ Branch 0 taken 586 times.
✗ Branch 1 not taken.
586 if(combo!=0)
5509 {
5510 586 putcombo(dest,x, y, combo, cset);
5511 586 }
5512 586 }
5513
5514 293 void overcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5515 {
5516
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 74 times.
293 if(combo!=0)
5517 {
5518 219 overcombo(dest,x, y, combo, cset);
5519 219 }
5520 293 }
5521
5522 125 void showbombeddoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t offx, int32_t offy)
5523 {
5524 125 int32_t d = scr->door_combo_set;
5525
5526
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 37 times.
125 switch(side)
5527 {
5528 case up:
5529 86 putcombo_not_zero(dest,((7&15)<<4) + offx,(7&0xF0) + offy,
5530 43 DoorComboSets[d].doorcombo_u[dt_bomb][0],
5531 43 DoorComboSets[d].doorcset_u[dt_bomb][0]);
5532 86 putcombo_not_zero(dest,((8&15)<<4) + offx,(8&0xF0) + offy,
5533 43 DoorComboSets[d].doorcombo_u[dt_bomb][1],
5534 43 DoorComboSets[d].doorcset_u[dt_bomb][1]);
5535 86 putcombo_not_zero(dest,((23&15)<<4) + offx,(23&0xF0) + offy,
5536 43 DoorComboSets[d].doorcombo_u[dt_bomb][2],
5537 43 DoorComboSets[d].doorcset_u[dt_bomb][2]);
5538 86 putcombo_not_zero(dest,((24&15)<<4) + offx,(24&0xF0) + offy,
5539 43 DoorComboSets[d].doorcombo_u[dt_bomb][3],
5540 43 DoorComboSets[d].doorcset_u[dt_bomb][3]);
5541 86 overcombo_not_zero(dest,((39&15)<<4) + offx,(39&0xF0) + offy,
5542 43 DoorComboSets[d].bombdoorcombo_u[0],
5543 43 DoorComboSets[d].bombdoorcset_u[0]);
5544 86 overcombo_not_zero(dest,((40&15)<<4) + offx,(40&0xF0) + offy,
5545 43 DoorComboSets[d].bombdoorcombo_u[1],
5546 43 DoorComboSets[d].bombdoorcset_u[1]);
5547 43 break;
5548
5549 case down:
5550 78 putcombo_not_zero(dest,((151&15)<<4) + offx,(151&0xF0) + offy,
5551 39 DoorComboSets[d].doorcombo_d[dt_bomb][0],
5552 39 DoorComboSets[d].doorcset_d[dt_bomb][0]);
5553 78 putcombo_not_zero(dest,((152&15)<<4) + offx,(152&0xF0) + offy,
5554 39 DoorComboSets[d].doorcombo_d[dt_bomb][1],
5555 39 DoorComboSets[d].doorcset_d[dt_bomb][1]);
5556 78 putcombo_not_zero(dest,((167&15)<<4) + offx,(167&0xF0) + offy,
5557 39 DoorComboSets[d].doorcombo_d[dt_bomb][2],
5558 39 DoorComboSets[d].doorcset_d[dt_bomb][2]);
5559 78 putcombo_not_zero(dest,((168&15)<<4) + offx,(168&0xF0) + offy,
5560 39 DoorComboSets[d].doorcombo_d[dt_bomb][3],
5561 39 DoorComboSets[d].doorcset_d[dt_bomb][3]);
5562 78 overcombo_not_zero(dest,((135&15)<<4) + offx,(135&0xF0) + offy,
5563 39 DoorComboSets[d].bombdoorcombo_d[0],
5564 39 DoorComboSets[d].bombdoorcset_d[0]);
5565 78 overcombo_not_zero(dest,((136&15)<<4) + offx,(136&0xF0) + offy,
5566 39 DoorComboSets[d].bombdoorcombo_d[1],
5567 39 DoorComboSets[d].bombdoorcset_d[1]);
5568 39 break;
5569
5570 case left:
5571 12 putcombo_not_zero(dest,((64&15)<<4) + offx,(64&0xF0) + offy,
5572 6 DoorComboSets[d].doorcombo_l[dt_bomb][0],
5573 6 DoorComboSets[d].doorcset_l[dt_bomb][0]);
5574 12 putcombo_not_zero(dest,((65&15)<<4) + offx,(65&0xF0) + offy,
5575 6 DoorComboSets[d].doorcombo_l[dt_bomb][1],
5576 6 DoorComboSets[d].doorcset_l[dt_bomb][1]);
5577 12 putcombo_not_zero(dest,((80&15)<<4) + offx,(80&0xF0) + offy,
5578 6 DoorComboSets[d].doorcombo_l[dt_bomb][2],
5579 6 DoorComboSets[d].doorcset_l[dt_bomb][2]);
5580 12 putcombo_not_zero(dest,((81&15)<<4) + offx,(81&0xF0) + offy,
5581 6 DoorComboSets[d].doorcombo_l[dt_bomb][3],
5582 6 DoorComboSets[d].doorcset_l[dt_bomb][3]);
5583 12 putcombo_not_zero(dest,((96&15)<<4) + offx,(96&0xF0) + offy,
5584 6 DoorComboSets[d].doorcombo_l[dt_bomb][4],
5585 6 DoorComboSets[d].doorcset_l[dt_bomb][4]);
5586 12 putcombo_not_zero(dest,((97&15)<<4) + offx,(97&0xF0) + offy,
5587 6 DoorComboSets[d].doorcombo_l[dt_bomb][5],
5588 6 DoorComboSets[d].doorcset_l[dt_bomb][5]);
5589 12 overcombo_not_zero(dest,((66&15)<<4) + offx,(66&0xF0) + offy,
5590 6 DoorComboSets[d].bombdoorcombo_l[0],
5591 6 DoorComboSets[d].bombdoorcset_l[0]);
5592 12 overcombo_not_zero(dest,((82&15)<<4) + offx,(82&0xF0) + offy,
5593 6 DoorComboSets[d].bombdoorcombo_l[1],
5594 6 DoorComboSets[d].bombdoorcset_l[1]);
5595 12 overcombo_not_zero(dest,((98&15)<<4) + offx,(98&0xF0) + offy,
5596 6 DoorComboSets[d].bombdoorcombo_l[2],
5597 6 DoorComboSets[d].bombdoorcset_l[2]);
5598 6 break;
5599
5600 case right:
5601 74 putcombo_not_zero(dest,((78&15)<<4) + offx,(78&0xF0) + offy,
5602 37 DoorComboSets[d].doorcombo_r[dt_bomb][0],
5603 37 DoorComboSets[d].doorcset_r[dt_bomb][0]);
5604 74 putcombo_not_zero(dest,((79&15)<<4) + offx,(79&0xF0) + offy,
5605 37 DoorComboSets[d].doorcombo_r[dt_bomb][1],
5606 37 DoorComboSets[d].doorcset_r[dt_bomb][1]);
5607 74 putcombo_not_zero(dest,((94&15)<<4) + offx,(94&0xF0) + offy,
5608 37 DoorComboSets[d].doorcombo_r[dt_bomb][2],
5609 37 DoorComboSets[d].doorcset_r[dt_bomb][2]);
5610 74 putcombo_not_zero(dest,((95&15)<<4) + offx,(95&0xF0) + offy,
5611 37 DoorComboSets[d].doorcombo_r[dt_bomb][3],
5612 37 DoorComboSets[d].doorcset_r[dt_bomb][3]);
5613 74 putcombo_not_zero(dest,((110&15)<<4) + offx,(110&0xF0) + offy,
5614 37 DoorComboSets[d].doorcombo_r[dt_bomb][4],
5615 37 DoorComboSets[d].doorcset_r[dt_bomb][4]);
5616 74 putcombo_not_zero(dest,((111&15)<<4) + offx,(111&0xF0) + offy,
5617 37 DoorComboSets[d].doorcombo_r[dt_bomb][5],
5618 37 DoorComboSets[d].doorcset_r[dt_bomb][5]);
5619 74 overcombo_not_zero(dest,((77&15)<<4) + offx,(77&0xF0) + offy,
5620 37 DoorComboSets[d].bombdoorcombo_r[0],
5621 37 DoorComboSets[d].bombdoorcset_r[0]);
5622 74 overcombo_not_zero(dest,((93&15)<<4) + offx,(93&0xF0) + offy,
5623 37 DoorComboSets[d].bombdoorcombo_r[1],
5624 37 DoorComboSets[d].bombdoorcset_r[1]);
5625 74 overcombo_not_zero(dest,((109&15)<<4) + offx,(109&0xF0) + offy,
5626 37 DoorComboSets[d].bombdoorcombo_r[2],
5627 37 DoorComboSets[d].bombdoorcset_r[2]);
5628 37 break;
5629 }
5630 125 }
5631
5632 5346447 void openshutters(mapscr* scr)
5633 {
5634 5346447 bool opened_door = false;
5635
2/2
✓ Branch 0 taken 5346447 times.
✓ Branch 1 taken 21385788 times.
26732235 for(int32_t i=0; i<4; i++)
5636
2/2
✓ Branch 0 taken 21381830 times.
✓ Branch 1 taken 3958 times.
21389746 if(scr->door[i]==dSHUTTER)
5637 {
5638 3958 putdoor(scr, scrollbuf, i, dOPENSHUTTER);
5639 3958 scr->door[i]=dOPENSHUTTER;
5640 3958 opened_door = true;
5641 3958 }
5642
5643 5346447 auto& combo_cache = combo_caches::shutter;
5644 2012538143 for_every_combo_in_screen(create_screen_handles(scr), [&](const auto& handle) {
5645
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2005581069 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1610624 times.
2007191696 if (!combo_cache.minis[handle.data()].shutter)
5646 2007191693 return;
5647 3 auto cid = handle.data();
5648 3 auto& cmb = handle.combo();
5649
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
5650 {
5651 3 auto& trig = cmb.triggers[idx];
5652
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if(trig.triggerflags[0] & combotriggerSHUTTER)
5653 {
5654 3 do_trigger_combo(handle, idx);
5655
1/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if(handle.data() != cid) break;
5656 }
5657 }
5658 2007191696 });
5659
5660
2/2
✓ Branch 0 taken 5343716 times.
✓ Branch 1 taken 2731 times.
5346447 if(opened_door)
5661 2731 sfx(WAV_DOOR,128);
5662 5346447 }
5663
5664 15104581 void clear_darkroom_bitmaps()
5665 {
5666 15104581 clear_to_color(darkscr_bmp, game->get_darkscr_color());
5667 15104581 clear_to_color(darkscr_bmp_trans, game->get_darkscr_color());
5668 15104581 }
5669
5670 16017890 bool is_dark(const mapscr* scr)
5671 {
5672 16017890 bool dark = scr->flags&fDARK;
5673
2/2
✓ Branch 0 taken 3722 times.
✓ Branch 1 taken 16014168 times.
16017890 if (region_is_lit) return !dark;
5674 16014168 return dark;
5675 16017890 }
5676
5677 39213 bool scrolling_is_dark(const mapscr* scr)
5678 {
5679 39213 bool dark = scr->flags&fDARK;
5680
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 39211 times.
39213 if (scrolling_region_is_lit) return !dark;
5681 39211 return dark;
5682 39213 }
5683
5684 36734 bool is_any_dark()
5685 {
5686 36734 bool dark = false;
5687 74724 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
5688 37990 dark |= (bool)(is_dark(scr));
5689 37990 });
5690 36734 return dark;
5691 }
5692
5693 404 static mapscr prev_origin_scrs[7];
5694 404 static std::set<int> loadscr_ffc_script_ids_to_remove;
5695
5696 static void handle_screen_overlay(const std::vector<mapscr*>& screens)
5697 {
5698 mapscr* base_scr = screens[0];
5699 mapscr* previous_scr = &prev_origin_scrs[0];
5700
5701 for (int i = 0; i < 176; i++)
5702 {
5703 if (base_scr->data[i] == 0)
5704 {
5705 base_scr->data[i] = previous_scr->data[i];
5706 base_scr->sflag[i] = previous_scr->sflag[i];
5707 base_scr->cset[i] = previous_scr->cset[i];
5708 }
5709 }
5710
5711 for (int i = 0; i < 6; i++)
5712 {
5713 if (previous_scr->layermap[i] > 0 && base_scr->layermap[i] > 0)
5714 {
5715 int lm = (base_scr->layermap[i]-1)*MAPSCRS+base_scr->layerscreen[i];
5716 int fm = (previous_scr->layermap[i]-1)*MAPSCRS+previous_scr->layerscreen[i];
5717
5718 for (int j = 0; j < 176; j++)
5719 {
5720 if (TheMaps[lm].data[j] == 0)
5721 {
5722 TheMaps[lm].data[j] = TheMaps[fm].data[j];
5723 TheMaps[lm].sflag[j] = TheMaps[fm].sflag[j];
5724 TheMaps[lm].cset[j] = TheMaps[fm].cset[j];
5725 }
5726 }
5727 }
5728 }
5729
5730 for (int i = 1; i <= 6; i++)
5731 {
5732 mapscr* scr = screens[i];
5733 previous_scr = &prev_origin_scrs[i];
5734
5735 if (scr->layermap[i] > 0)
5736 {
5737 for (int y = 0; y < 11; y++)
5738 {
5739 for (int x = 0; x < 16; x++)
5740 {
5741 int c = y*16+x;
5742
5743 if (scr->data[c]==0)
5744 {
5745 scr->data[c] = previous_scr->data[c];
5746 scr->sflag[c] = previous_scr->sflag[c];
5747 scr->cset[c] = previous_scr->cset[c];
5748 }
5749 }
5750 }
5751 }
5752 }
5753 }
5754
5755 37074 static void load_a_screen_and_layers_init(int dmap, int screen, int ldir, bool screen_overlay, bool ffc_overlay)
5756 {
5757 37074 std::vector<mapscr*> screens;
5758
5759
1/2
✓ Branch 0 taken 37074 times.
✗ Branch 1 not taken.
37074 const mapscr* source = get_canonical_scr(cur_map, screen);
5760
2/4
✓ Branch 0 taken 37074 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37074 times.
✗ Branch 3 not taken.
37074 mapscr* base_scr = new mapscr(*source);
5761 37074 temporary_screens[screen*7] = base_scr;
5762
1/2
✓ Branch 0 taken 37074 times.
✗ Branch 1 not taken.
37074 screens.push_back(base_scr);
5763
5764 37074 base_scr->valid |= mVALID; // layer 0 is always valid
5765
5766
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35830 times.
37074 if (screen == cur_screen)
5767 35830 origin_scr = base_scr;
5768
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35830 times.
37074 if (screen == hero_screen)
5769 35830 hero_scr = prev_hero_scr = base_scr;
5770
5771
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 36955 times.
37074 if (source->script > 0)
5772
1/2
✓ Branch 0 taken 119 times.
✗ Branch 1 not taken.
119 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
5773
5774
2/2
✓ Branch 0 taken 37074 times.
✓ Branch 1 taken 222444 times.
259518 for (int i = 0; i < 6; i++)
5775 {
5776
2/2
✓ Branch 0 taken 173412 times.
✓ Branch 1 taken 49032 times.
222444 if(source->layermap[i]>0)
5777 {
5778
3/6
✓ Branch 0 taken 49032 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49032 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 49032 times.
✗ Branch 5 not taken.
49032 mapscr* layer_scr = new mapscr(*get_canonical_scr(source->layermap[i]-1, source->layerscreen[i]));
5779 49032 layer_scr->map = cur_map;
5780 49032 layer_scr->screen = screen;
5781
1/2
✓ Branch 0 taken 49032 times.
✗ Branch 1 not taken.
49032 screens.push_back(layer_scr);
5782 49032 }
5783 else
5784 {
5785
1/2
✓ Branch 0 taken 173412 times.
✗ Branch 1 not taken.
173412 mapscr* layer_scr = new mapscr();
5786 173412 layer_scr->map = cur_map;
5787 173412 layer_scr->screen = screen;
5788
1/2
✓ Branch 0 taken 173412 times.
✗ Branch 1 not taken.
173412 screens.push_back(layer_scr);
5789 }
5790 222444 temporary_screens[screen*7+i+1] = screens[i+1];
5791 222444 }
5792
5793
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37074 times.
37074 if (screen_overlay)
5794 handle_screen_overlay(screens);
5795
5796
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 36930 times.
37074 if (ffc_overlay)
5797 {
5798 144 mapscr* previous_scr = &prev_origin_scrs[0];
5799
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 int num_ffcs = previous_scr->numFFC();
5800
2/2
✓ Branch 0 taken 4608 times.
✓ Branch 1 taken 144 times.
4752 for (int i = 0; i < num_ffcs; i++)
5801 {
5802
2/2
✓ Branch 0 taken 4334 times.
✓ Branch 1 taken 274 times.
4608 if ((previous_scr->ffcs[i].flags&ffc_carryover))
5803 {
5804
2/4
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 274 times.
✗ Branch 3 not taken.
274 auto& ffc = base_scr->getFFC(i) = previous_scr->ffcs[i];
5805 274 ffc.screen_spawned = screen;
5806
5807
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + i;
5808
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 loadscr_ffc_script_ids_to_remove.erase(ffc_id);
5809
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 274 times.
274 if (previous_scr->ffcs[i].flags&ffc_scriptreset)
5810 {
5811 FFCore.reset_script_engine_data(ScriptType::FFC, ffc_id);
5812 }
5813 274 }
5814 4608 }
5815 144 }
5816
5817
1/2
✓ Branch 0 taken 37074 times.
✗ Branch 1 not taken.
1142083 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
5818
1/2
✓ Branch 0 taken 37074 times.
✗ Branch 1 not taken.
37074 int num_ffcs = base_scr->numFFC();
5819
2/2
✓ Branch 0 taken 1105009 times.
✓ Branch 1 taken 37074 times.
1142083 for (word i = 0; i < num_ffcs; i++)
5820 {
5821 1105009 base_scr->ffcs[i].screen_spawned = screen;
5822
1/2
✓ Branch 0 taken 1105009 times.
✗ Branch 1 not taken.
1105009 base_scr->ffcs[i].x += offx;
5823
1/2
✓ Branch 0 taken 1105009 times.
✗ Branch 1 not taken.
1105009 base_scr->ffcs[i].y += offy;
5824 1105009 }
5825 37074 }
5826
5827 37074 static void load_a_screen_and_layers_post(int dmap, int screen, int ldir)
5828 {
5829 37074 mapscr* base_scr = get_scr(screen);
5830 37074 int mi = mapind(cur_map, screen);
5831
5832 // Apply perm secrets, if applicable.
5833
2/2
✓ Branch 0 taken 11519 times.
✓ Branch 1 taken 25555 times.
37074 if (canPermSecret(dmap, screen))
5834 {
5835
2/2
✓ Branch 0 taken 23031 times.
✓ Branch 1 taken 2524 times.
25555 if(game->maps[mi] & mSECRET) // if special stuff done before
5836 {
5837 2524 reveal_hidden_stairs(base_scr, screen, false);
5838 2524 trigger_secrets_for_screen(TriggerSource::SecretsScreenState, base_scr, false);
5839 2524 }
5840
2/2
✓ Branch 0 taken 25552 times.
✓ Branch 1 taken 3 times.
25555 if(game->maps[mi] & mLIGHTBEAM) // if special stuff done before
5841 {
5842
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (int layer = 0; layer <= 6; layer++)
5843 {
5844 21 mapscr* layer_scr = get_scr_layer(screen, layer);
5845
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 21 times.
3717 for (int pos = 0; pos < 176; pos++)
5846 {
5847 3696 newcombo const* cmb = &combobuf[layer_scr->data[pos]];
5848
2/2
✓ Branch 0 taken 3693 times.
✓ Branch 1 taken 3 times.
3696 if(cmb->type == cLIGHTTARGET)
5849 {
5850
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(cmb->usrflags&cflag1)) //Unlit version
5851 {
5852 3 layer_scr->data[pos] += 1;
5853 3 }
5854 3 }
5855 3696 }
5856 21 }
5857 3 }
5858 25555 }
5859
5860 37074 auto screen_handles = create_screen_handles(base_scr);
5861
5862 37074 int destlvl = DMaps[dmap].level;
5863 37074 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
5864 37074 toggle_gswitches_load(screen_handles);
5865
5866 37074 bool should_check_for_state_things = (screen < 0x80);
5867
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 36167 times.
37074 if (should_check_for_state_things)
5868 {
5869
2/2
✓ Branch 0 taken 35795 times.
✓ Branch 1 taken 372 times.
36167 if (game->maps[mi]&mLOCKBLOCK)
5870 372 remove_lockblocks(screen_handles);
5871
2/2
✓ Branch 0 taken 36109 times.
✓ Branch 1 taken 58 times.
36167 if (game->maps[mi]&mBOSSLOCKBLOCK)
5872 58 remove_bosslockblocks(screen_handles);
5873
2/2
✓ Branch 0 taken 36011 times.
✓ Branch 1 taken 156 times.
36167 if (game->maps[mi]&mCHEST)
5874 156 remove_chests(screen_handles);
5875
1/2
✓ Branch 0 taken 36167 times.
✗ Branch 1 not taken.
36167 if (game->maps[mi]&mLOCKEDCHEST)
5876 remove_lockedchests(screen_handles);
5877
2/2
✓ Branch 0 taken 36156 times.
✓ Branch 1 taken 11 times.
36167 if (game->maps[mi]&mBOSSCHEST)
5878 11 remove_bosschests(screen_handles);
5879
5880 36167 clear_xdoors_mi(screen_handles, mi, true);
5881 36167 clear_xstatecombos_mi(screen_handles, mi, true);
5882 14714360 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
5883 14678193 auto cid = handle.data();
5884 14678193 auto& cmb = handle.combo();
5885
4/4
✓ Branch 0 taken 14674176 times.
✓ Branch 1 taken 549385 times.
✓ Branch 2 taken 4017 times.
✓ Branch 3 taken 400 times.
15227978 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
5886 {
5887 549785 auto& trig = cmb.triggers[idx];
5888
2/4
✓ Branch 0 taken 549385 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 400 times.
✗ Branch 3 not taken.
549785 if (trig.triggerflags[4] & combotriggerSCREENLOAD)
5889 {
5890 do_trigger_combo(handle, idx);
5891 if(handle.data() != cid) break;
5892 }
5893 549785 }
5894 14678193 });
5895 36167 }
5896
5897 // check doors
5898
2/2
✓ Branch 0 taken 25554 times.
✓ Branch 1 taken 11520 times.
37074 if (isdungeon(dmap, screen))
5899 {
5900
2/2
✓ Branch 0 taken 46080 times.
✓ Branch 1 taken 11520 times.
57600 for(int32_t i=0; i<4; i++)
5901 {
5902 46080 int32_t door=base_scr->door[i];
5903
5904
5/5
✓ Branch 0 taken 5303 times.
✓ Branch 1 taken 36471 times.
✓ Branch 2 taken 2372 times.
✓ Branch 3 taken 230 times.
✓ Branch 4 taken 1704 times.
46080 switch(door)
5905 {
5906 case d1WAYSHUTTER:
5907 case dSHUTTER:
5908
3/4
✓ Branch 0 taken 1694 times.
✓ Branch 1 taken 3609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1694 times.
5303 if ((ldir^1)==i && screen == hero_screen)
5909 {
5910 1694 base_scr->door[i]=dOPENSHUTTER;
5911 1694 }
5912
5913 5303 get_screen_state(screen).open_doors = -4;
5914 5303 break;
5915
5916 case dLOCKED:
5917
3/4
✓ Branch 0 taken 2372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1473 times.
✓ Branch 3 taken 899 times.
2372 if(should_check_for_state_things && game->maps[mi]&(1<<i))
5918 {
5919 1473 base_scr->door[i]=dUNLOCKED;
5920 1473 }
5921
5922 2372 break;
5923
5924 case dBOSS:
5925
3/4
✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 168 times.
230 if(should_check_for_state_things && game->maps[mi]&(1<<i))
5926 {
5927 62 base_scr->door[i]=dOPENBOSS;
5928 62 }
5929
5930 230 break;
5931
5932 case dBOMB:
5933
3/4
✓ Branch 0 taken 1704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1087 times.
✓ Branch 3 taken 617 times.
1704 if(should_check_for_state_things && game->maps[mi]&(1<<i))
5934 {
5935 1087 base_scr->door[i]=dBOMBED;
5936 1087 }
5937
5938 1704 break;
5939 }
5940
5941 46080 update_door(base_scr, i, base_scr->door[i]);
5942
5943
4/4
✓ Branch 0 taken 41513 times.
✓ Branch 1 taken 4567 times.
✓ Branch 2 taken 736 times.
✓ Branch 3 taken 40777 times.
46080 if(door==dSHUTTER||door==d1WAYSHUTTER)
5944 {
5945 5303 base_scr->door[i]=door;
5946 5303 }
5947 46080 }
5948 11520 }
5949
5950
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 36937 times.
37074 if (!(base_scr->flags3 & fCYCLEONINIT))
5951 36937 return;
5952
5953
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 959 times.
1096 for (int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
5954 {
5955
4/4
✓ Branch 0 taken 822 times.
✓ Branch 1 taken 137 times.
✓ Branch 2 taken 377 times.
✓ Branch 3 taken 445 times.
959 if (j<0 || base_scr->layermap[j] > 0)
5956 {
5957 514 mapscr* layer_scr = get_scr_layer(screen, j + 1);
5958
3/4
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 377 times.
514 mapscr* layerscreen= (j<0 ? base_scr : layer_scr->valid ? layer_scr :
5959 &TheMaps[(base_scr->layermap[j]-1)*MAPSCRS]+base_scr->layerscreen[j]);
5960
5961
2/2
✓ Branch 0 taken 90464 times.
✓ Branch 1 taken 514 times.
90978 for(int32_t i=0; i<176; ++i)
5962 {
5963 90464 int32_t c=layerscreen->data[i];
5964
5965 // New screen flag: Cycle Combos At Screen Init
5966
5/6
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 90399 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
90464 if(combobuf[c].nextcombo != 0 && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
5967 {
5968 65 int32_t r = 0;
5969
5970
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 65 times.
149 while(combobuf[c].can_cycle() && r++ < 10)
5971 {
5972 84 newcombo const& cmb = combobuf[c];
5973 84 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
5974
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
5975 84 layerscreen->data[i] = cid;
5976
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 69 times.
84 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
5977
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
5978 84 c = layerscreen->data[i];
5979 }
5980 65 }
5981 90464 }
5982 514 }
5983 959 }
5984 37074 }
5985
5986 // Set `cur_screen` to `screen` and load new screens into temporary memory.
5987 //
5988 // Called anytime a player moves to a new screen (either via warping, scrolling, continue, starting
5989 // the game, etc...)
5990 //
5991 // Note: for regions, only the initial screen load calls this function. Simply walking between
5992 // screens in the same region does not use this, because every screen in a region is loaded into
5993 // temporary memory up front.
5994 //
5995 // If scr >= 0x80, `hero_screen` will be saved to `home_screen` and also be loaded into
5996 // `special_warp_return_scr`.
5997 //
5998 // If origin_screen_overlay is true, the old origin_scr combos will be copied to the new origin_scr combos
5999 // on all layers (but only where the new screen has a 0 combo).
6000 //
6001 // TODO: loadscr should set curdmap, but currently callers do that.
6002 35830 void loadscr(int32_t destdmap, int32_t screen, int32_t ldir, bool origin_screen_overlay, bool no_x80_dir)
6003 {
6004 35830 zapp_reporting_set_tag("screen", screen);
6005
2/2
✓ Branch 0 taken 8917 times.
✓ Branch 1 taken 26913 times.
35830 if (destdmap != -1)
6006 8917 zapp_reporting_set_tag("dmap", destdmap);
6007
6008 35830 int32_t orig_destdmap = destdmap;
6009
2/2
✓ Branch 0 taken 8917 times.
✓ Branch 1 taken 26913 times.
35830 if (destdmap < 0) destdmap = cur_dmap;
6010
6011
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35830 times.
35830 if (replay_is_active())
6012 {
6013
1/2
✓ Branch 0 taken 35830 times.
✗ Branch 1 not taken.
35830 if (replay_get_mode() == ReplayMode::ManualTakeover)
6014 replay_stop_manual_takeover();
6015
6016
2/2
✓ Branch 0 taken 26913 times.
✓ Branch 1 taken 8917 times.
35830 if (orig_destdmap != -1)
6017 {
6018
2/2
✓ Branch 0 taken 7844 times.
✓ Branch 1 taken 1073 times.
8917 if (strlen(DMaps[orig_destdmap].name) > 0)
6019 {
6020
1/2
✓ Branch 0 taken 7844 times.
✗ Branch 1 not taken.
7844 replay_step_comment(fmt::format("dmap={} {}", orig_destdmap, DMaps[orig_destdmap].name));
6021 7844 }
6022 else
6023 {
6024
1/2
✓ Branch 0 taken 1073 times.
✗ Branch 1 not taken.
1073 replay_step_comment(fmt::format("dmap={}", orig_destdmap));
6025 }
6026 8917 }
6027 35830 replay_step_comment_loadscr(screen);
6028
6029 // Reset the rngs and frame count so that recording steps can be modified without impacting
6030 // behavior of later screens.
6031 35830 replay_sync_rng();
6032 35830 }
6033
6034
2/2
✓ Branch 0 taken 1707454 times.
✓ Branch 1 taken 35830 times.
1743284 for (auto& state : get_screen_states())
6035 1707454 state.second.triggered_secrets = false;
6036 35830 slopes.clear();
6037 35830 Hero.clear_platform_ffc();
6038 35830 timeExitAllGenscript(GENSCR_ST_CHANGE_SCREEN);
6039 35830 clear_darkroom_bitmaps();
6040 35830 msgscr = nullptr;
6041
6042
2/2
✓ Branch 0 taken 50387168 times.
✓ Branch 1 taken 35830 times.
50422998 for (word x=0; x<animated_combos; x++)
6043 {
6044
2/2
✓ Branch 0 taken 20919169 times.
✓ Branch 1 taken 29467999 times.
50387168 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6045 {
6046 20919169 combobuf[animated_combo_table4[x][0]].aclk = 0;
6047 20919169 }
6048 50387168 }
6049 35830 reset_combo_animations2();
6050 35830 region_is_lit = false;
6051
6052 // Legacy features (combo and ffc overlays) may need the previous origin screens during loading
6053 // of the new ones.
6054 35830 bool origin_ffc_overlay = false;
6055
2/2
✓ Branch 0 taken 34700 times.
✓ Branch 1 taken 1130 times.
35830 if (origin_scr)
6056 {
6057
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 34698 times.
34700 if (!(origin_scr->flags5&fNOFFCARRYOVER))
6058 {
6059 34698 int c = origin_scr->numFFC();
6060
2/2
✓ Branch 0 taken 34554 times.
✓ Branch 1 taken 1038879 times.
1073433 for (int i = 0; i < c; i++)
6061 {
6062
2/2
✓ Branch 0 taken 1038735 times.
✓ Branch 1 taken 144 times.
1038879 if (origin_scr->ffcs[i].flags&ffc_carryover)
6063 {
6064 144 origin_ffc_overlay = true;
6065 144 break;
6066 }
6067 1038735 }
6068 34698 }
6069
6070
3/4
✓ Branch 0 taken 34700 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
✓ Branch 3 taken 34556 times.
34700 if (origin_screen_overlay || origin_ffc_overlay)
6071 {
6072
2/2
✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 144 times.
1152 for (int i = 0; i <= 6; i++)
6073 {
6074 1008 mapscr* prev_scr = get_scr_layer(cur_screen, i);
6075
1/2
✓ Branch 0 taken 1008 times.
✗ Branch 1 not taken.
1008 if (prev_scr)
6076 1008 prev_origin_scrs[i] = *prev_scr;
6077 else
6078 prev_origin_scrs[i] = {};
6079 1008 }
6080 144 }
6081 34700 }
6082
6083 // Based on origin_ffc_overlay, some ffc scripts don't get reset. This set starts with all of
6084 // them, but scripts that need their data to persist will be removed.
6085 35830 loadscr_ffc_script_ids_to_remove.clear();
6086
2/2
✓ Branch 0 taken 20148880 times.
✓ Branch 1 taken 35830 times.
20184710 for (auto& key : scriptEngineDatas | std::views::keys)
6087 {
6088
2/2
✓ Branch 0 taken 19026975 times.
✓ Branch 1 taken 1121905 times.
20148880 if (key.first == ScriptType::FFC)
6089 1121905 loadscr_ffc_script_ids_to_remove.insert(key.second);
6090 }
6091
6092 35830 load_region(destdmap, screen);
6093
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 34923 times.
35830 home_screen = screen >= 0x80 ? hero_screen : cur_screen;
6094 35830 hero_screen = screen;
6095
6096 35830 cpos_clear_all();
6097 35830 FFCore.clear_script_engine_data_of_type(ScriptType::Screen);
6098 35830 FFCore.clear_combo_scripts();
6099 35830 FFCore.deallocateAllScriptOwnedOfType(ScriptType::Screen);
6100 35830 FFCore.deallocateAllScriptOwnedOfType(ScriptType::Combo);
6101
6102
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35666 times.
35830 if (is_in_scrolling_region())
6103 {
6104
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6105 {
6106
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6107 {
6108
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool screen_overlay = origin_screen_overlay && screen == cur_screen;
6109
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool ffc_overlay = origin_ffc_overlay && screen == cur_screen;
6110 1408 load_a_screen_and_layers_init(destdmap, screen, ldir, screen_overlay, ffc_overlay);
6111 1408 }
6112 20992 }
6113 164 }
6114 else
6115 {
6116 35666 load_a_screen_and_layers_init(destdmap, screen, ldir, origin_screen_overlay, origin_ffc_overlay);
6117 }
6118
6119 35830 prepare_current_region_handles();
6120
6121
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35666 times.
35830 if (is_in_scrolling_region())
6122 {
6123
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6124 {
6125
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6126 {
6127 1408 load_a_screen_and_layers_post(destdmap, screen, ldir);
6128 1408 }
6129 20992 }
6130 164 }
6131 else
6132 {
6133 35666 load_a_screen_and_layers_post(destdmap, screen, ldir);
6134 }
6135
6136 // If on a special screen, load the screen the player is currently on (home_screen) into special_warp_return_scr.
6137
2/2
✓ Branch 0 taken 34923 times.
✓ Branch 1 taken 907 times.
35830 if (screen >= 0x80)
6138
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 431 times.
907 loadscr_old(orig_destdmap, home_screen, no_x80_dir ? -1 : ldir, origin_screen_overlay);
6139
6140 35830 update_slope_comboposes();
6141 35830 cpos_force_update();
6142 35830 trig_trigger_groups();
6143
6144
2/2
✓ Branch 0 taken 1121631 times.
✓ Branch 1 taken 35830 times.
1157461 for (int index : loadscr_ffc_script_ids_to_remove)
6145 {
6146 1121631 FFCore.deallocateAllScriptOwned(ScriptType::FFC, index);
6147 1121631 FFCore.reset_script_engine_data(ScriptType::FFC, index);
6148 }
6149
6150 // "extended height mode" includes the top 56 pixels as part of the visible mapscr viewport,
6151 // allowing for regions to display 4 more rows of combos (as many as ALTTP does). This part of
6152 // screen is normally reserved for the passive subscreen, but in this mode mapscr combos are drawn below it.
6153 // It is up to the quest designer to make their subscreen be actually transparent.
6154 //
6155 // When not in "extended height mode" (otherwise 56 is 0):
6156 // - playing_field_offset: 56, but changes during earthquakes
6157 // - original_playing_field_offset: always 56
6158 //
6159 // These values are used to adjust where things are drawn on screen to account for the passive subscreen. Examples:
6160 // - yofs of sprites
6161 // - bitmap y offsets in draw_screen
6162 // - drawing offsets for putscr, do_layer
6163 // - drawing offsets for various calls to overtile16 (see bomb weapon explosion)
6164 // - lots more
6165 //
6166 // TODO: consider refactor of yofs, make yofs start as 0 by default and add playing_field_offset at draw time?
6167
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 35688 times.
35830 if (is_extended_height_mode())
6168 {
6169 142 playing_field_offset = 0;
6170 142 original_playing_field_offset = 0;
6171 // A few sprites exist as globals, so we must manually reset them.
6172 142 Hero.yofs = 0;
6173 142 mblock2.yofs = 0;
6174 142 }
6175 else
6176 {
6177 35688 mblock2.yofs = Hero.yofs = playing_field_offset = 56;
6178 35688 original_playing_field_offset = 56;
6179 }
6180 35830 is_any_room_dark = is_any_dark();
6181
6182 35830 game->load_portal();
6183 35830 throwGenScriptEvent(GENSCR_EVENT_CHANGE_SCREEN);
6184
3/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 35795 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
35830 if (Hero.lift_wpn && get_qr(qr_CARRYABLE_NO_ACROSS_SCREEN))
6185 {
6186 delete Hero.lift_wpn;
6187 Hero.lift_wpn = nullptr;
6188 }
6189
6190 35830 enemy_spawning_has_checked_been_here = false;
6191 35830 markBmap(-1, hero_screen);
6192 35830 Hero.maybe_begin_advanced_maze();
6193 35830 }
6194
6195 // Don't use this directly! Use `loadscr` instead.
6196 907 void loadscr_old(int32_t destdmap, int32_t screen,int32_t ldir,bool overlay)
6197 {
6198
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int32_t destlvl = DMaps[destdmap < 0 ? cur_dmap : destdmap].level;
6199
6200 907 mapscr previous_scr = *special_warp_return_scr;
6201 907 mapscr* scr = special_warp_return_scr;
6202
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 const mapscr* source = get_canonical_scr(cur_map, screen);
6203
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 *scr = *source;
6204
6205
2/2
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 907 times.
6349 for (int i = 1; i <= 6; i++)
6206 {
6207
2/2
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 5059 times.
5442 if (scr->layermap[i-1] > 0)
6208
2/4
✓ Branch 0 taken 383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
383 special_warp_return_scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6209 else
6210 5059 special_warp_return_scrs[i] = {};
6211 5442 }
6212
6213 907 scr->valid |= mVALID; //layer 0 is always valid
6214
6215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 907 times.
907 if ( source->script > 0 )
6216 {
6217 scr->script = source->script;
6218 for ( int32_t q = 0; q < 8; q++ )
6219 {
6220 scr->screeninitd[q] = source->screeninitd[q];
6221 }
6222 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6223 }
6224 else
6225 {
6226 907 scr->script = 0;
6227 }
6228
6229
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 if(overlay)
6230 {
6231 for(int32_t c=0; c< 176; ++c)
6232 {
6233 if(scr->data[c]==0)
6234 {
6235 scr->data[c]=previous_scr.data[c];
6236 scr->sflag[c]=previous_scr.sflag[c];
6237 scr->cset[c]=previous_scr.cset[c];
6238 }
6239 }
6240
6241 for(int32_t i=0; i<6; i++)
6242 {
6243 if(previous_scr.layermap[i]>0 && scr->layermap[i]>0)
6244 {
6245 int32_t lm = (scr->layermap[i]-1)*MAPSCRS+scr->layerscreen[i];
6246 int32_t fm = (previous_scr.layermap[i]-1)*MAPSCRS+previous_scr.layerscreen[i];
6247
6248 for(int32_t c=0; c< 176; ++c)
6249 {
6250 if(TheMaps[lm].data[c]==0)
6251 {
6252 TheMaps[lm].data[c] = TheMaps[fm].data[c];
6253 TheMaps[lm].sflag[c] = TheMaps[fm].sflag[c];
6254 TheMaps[lm].cset[c] = TheMaps[fm].cset[c];
6255 }
6256 }
6257 }
6258 }
6259 }
6260
6261
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
29900 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6262
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int c = scr->numFFC();
6263
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 28993 times.
29900 for (word i = 0; i < c; i++)
6264 {
6265 28993 scr->ffcs[i].screen_spawned = screen;
6266
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].x += offx;
6267
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].y += offy;
6268 28993 }
6269
6270 907 int mi = mapind(cur_map, screen);
6271
6272 // Apply perm secrets, if applicable.
6273
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if(canPermSecret(destdmap,screen))
6274 {
6275
3/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 332 times.
536 if(game->maps[mi]&mSECRET) // if special stuff done before
6276 {
6277
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 reveal_hidden_stairs(scr, screen, false);
6278
6279
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
6280
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 get_screen_state(special_warp_return_scr->screen).triggered_secrets = true;
6281 204 bool do_replay_comment = true;
6282 204 bool from_active_screen = false;
6283
2/4
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✗ Branch 3 not taken.
204 trigger_secrets_for_screen_internal(create_screen_handles(special_warp_return_scr), from_active_screen, false, -1, do_replay_comment);
6284 204 }
6285
2/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✗ Branch 3 not taken.
536 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6286 {
6287 for (int layer = 0; layer <= 6; layer++)
6288 {
6289 mapscr* tscr = &special_warp_return_scrs[layer];
6290 for (int pos = 0; pos < 176; pos++)
6291 {
6292 newcombo const* cmb = &combobuf[tscr->data[pos]];
6293 if(cmb->type == cLIGHTTARGET)
6294 {
6295 if(!(cmb->usrflags&cflag1)) //Unlit version
6296 {
6297 tscr->data[pos] += 1;
6298 }
6299 }
6300 }
6301 }
6302 }
6303 536 }
6304
6305 screen_handles_t screen_handles;
6306
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 6349 times.
7256 for (int i = 0; i <= 6; i++)
6307
3/4
✓ Branch 0 taken 6349 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1289 times.
✓ Branch 3 taken 5060 times.
6349 screen_handles[i] = {scr, special_warp_return_scrs[i].is_valid() ? &special_warp_return_scrs[i] : nullptr, screen, i};
6308
6309
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 907 times.
✗ Branch 3 not taken.
907 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6310
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 toggle_gswitches_load(screen_handles);
6311
6312
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 902 times.
907 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6313 {
6314
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 remove_lockblocks(screen_handles);
6315 5 }
6316
6317
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 906 times.
907 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6318 {
6319
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6320 1 }
6321
6322
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mCHEST) // if special stuff done before
6323 {
6324 remove_chests(screen_handles);
6325 }
6326
6327
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6328 {
6329 remove_lockedchests(screen_handles);
6330 }
6331
6332
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6333 {
6334 remove_bosschests(screen_handles);
6335 }
6336
6337
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xdoors(screen_handles, true);
6338
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xstatecombos(screen_handles, true);
6339
6340
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
227771 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
6341 226864 auto cid = handle.data();
6342 226864 auto& cmb = handle.combo();
6343
2/4
✓ Branch 0 taken 226864 times.
✓ Branch 1 taken 531 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
227395 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
6344 {
6345 531 auto& trig = cmb.triggers[idx];
6346
1/4
✓ Branch 0 taken 531 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
531 if (trig.triggerflags[4] & combotriggerSCREENLOAD)
6347 {
6348 do_trigger_combo(handle, idx);
6349 if(handle.data() != cid) break;
6350 }
6351 531 }
6352 226864 });
6353
6354 // check doors
6355
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if (isdungeon(destdmap, screen))
6356 {
6357
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 371 times.
1855 for(int32_t i=0; i<4; i++)
6358 {
6359 1484 int32_t door=scr->door[i];
6360
6361
4/4
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 89 times.
✓ Branch 3 taken 1295 times.
1484 switch(door)
6362 {
6363 case d1WAYSHUTTER:
6364 case dSHUTTER:
6365
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1295 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1295 if ((ldir^1)==i && screen == home_screen)
6366 {
6367 scr->door[i]=dOPENSHUTTER;
6368 }
6369
6370
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 1190 times.
1295 get_screen_state(screen).open_doors = -4;
6371 105 break;
6372
6373 case dLOCKED:
6374
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 80 times.
91 if(game->maps[mi]&(1<<i))
6375 {
6376 80 scr->door[i]=dUNLOCKED;
6377 80 }
6378
6379 91 break;
6380
6381 case dBOSS:
6382
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 5 times.
9 if(game->maps[mi]&(1<<i))
6383 {
6384 5 scr->door[i]=dOPENBOSS;
6385 5 }
6386
6387 9 break;
6388
6389 case dBOMB:
6390
3/4
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 51 times.
89 if(game->maps[mi]&(1<<i))
6391 {
6392 51 scr->door[i]=dBOMBED;
6393 51 }
6394
6395 89 break;
6396 }
6397
6398
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 1190 times.
294 update_door(scr, i, scr->door[i]);
6399
6400
4/4
✓ Branch 0 taken 1390 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1379 times.
1484 if(door==dSHUTTER||door==d1WAYSHUTTER)
6401 {
6402 105 scr->door[i]=door;
6403 105 }
6404 1484 }
6405 371 }
6406
6407
2/2
✓ Branch 0 taken 6915 times.
✓ Branch 1 taken 625 times.
7256 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6408 {
6409
4/4
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 1473 times.
✓ Branch 2 taken 2763 times.
✓ Branch 3 taken 2679 times.
6915 if (j<0 || scr->layermap[j] > 0)
6410 {
6411
4/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 907 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 1 times.
4236 mapscr *layerscreen= (j<0 ? scr : special_warp_return_scrs[j+1].valid ? &special_warp_return_scrs[j+1] :
6412 1 &TheMaps[(scr->layermap[j]-1)*MAPSCRS]+scr->layerscreen[j]);
6413
6414
2/2
✓ Branch 0 taken 224660 times.
✓ Branch 1 taken 3670 times.
228330 for(int32_t i=0; i<176; ++i)
6415 {
6416 224660 int32_t c=layerscreen->data[i];
6417
6418 // New screen flag: Cycle Combos At Screen Init
6419
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 224654 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2380 times.
✓ Branch 7 taken 2380 times.
224660 if(combobuf[c].nextcombo != 0 && (scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6420 {
6421 2380 int32_t r = 0;
6422
6423
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2380 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2380 while(combobuf[c].can_cycle() && r++ < 10)
6424 {
6425 newcombo const& cmb = combobuf[c];
6426 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6427 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6428 layerscreen->data[i] = cid;
6429 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6430 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6431 c = layerscreen->data[i];
6432 }
6433 }
6434 227040 }
6435 3670 }
6436 6349 }
6437 5385 }
6438
6439 // Load screen (and layers). Unlike loadscr, this doesn't load to the global temporary_screens, but
6440 // instead returns an array of mapscr.
6441 // Used to draw/save the map.
6442 45680 std::array<mapscr, 7> loadscr2(int32_t screen)
6443 {
6444 45680 std::array<mapscr, 7> scrs;
6445 45680 mapscr* scr = &scrs[0];
6446
6447
2/2
✓ Branch 0 taken 64716181 times.
✓ Branch 1 taken 45680 times.
64761861 for(word x=0; x<animated_combos; x++)
6448 {
6449
2/2
✓ Branch 0 taken 31963685 times.
✓ Branch 1 taken 32752496 times.
64716181 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6450 {
6451 32752496 combobuf[animated_combo_table4[x][0]].aclk=0;
6452 32752496 }
6453 64716181 }
6454
6455
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 const mapscr* source = get_canonical_scr(cur_map, screen);
6456
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!source->is_valid())
6457 {
6458 scrs[0].valid = 0;
6459 return scrs;
6460 }
6461
6462
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 *scr = *get_canonical_scr(cur_map, screen);
6463
2/2
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
319760 for (int i = 1; i <= 6; i++)
6464 {
6465
2/2
✓ Branch 0 taken 64814 times.
✓ Branch 1 taken 209266 times.
274080 if (scr->layermap[i-1] > 0)
6466
2/4
✓ Branch 0 taken 64814 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64814 times.
✗ Branch 3 not taken.
64814 scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6467 else
6468 209266 scrs[i] = {};
6469 274080 }
6470
6471 screen_handles_t screen_handles;
6472
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i < 7; i++)
6473
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103790 times.
✓ Branch 3 taken 215970 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
6474
6475 45680 int mi = mapind(cur_map, screen);
6476
6477
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45626 times.
✓ Branch 3 taken 54 times.
45680 if(canPermSecret(-1,screen))
6478 {
6479
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5730 times.
✓ Branch 3 taken 39896 times.
45626 if(game->maps[mi]&mSECRET) // if special stuff done before
6480 {
6481
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 reveal_hidden_stairs(scr, screen, false);
6482 5730 bool from_active_screen = false;
6483 5730 bool do_replay_comment = true;
6484
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 trigger_secrets_for_screen_internal(screen_handles, from_active_screen, false, -1, do_replay_comment);
6485 5730 }
6486
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45609 times.
✓ Branch 3 taken 17 times.
45626 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6487 {
6488
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 17 times.
136 for (int layer = 0; layer <= 6; layer++)
6489 {
6490 119 mapscr* tscr = &scrs[layer];
6491
2/2
✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 119 times.
21063 for (int pos = 0; pos < 176; pos++)
6492 {
6493 20944 newcombo const* cmb = &combobuf[tscr->data[pos]];
6494
2/2
✓ Branch 0 taken 20927 times.
✓ Branch 1 taken 17 times.
20944 if(cmb->type == cLIGHTTARGET)
6495 {
6496
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!(cmb->usrflags&cflag1)) //Unlit version
6497 {
6498 17 tscr->data[pos] += 1;
6499 17 }
6500 17 }
6501 20944 }
6502 119 }
6503 17 }
6504 45626 }
6505
6506
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 233 times.
✓ Branch 3 taken 45447 times.
45680 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6507 {
6508
1/2
✓ Branch 0 taken 233 times.
✗ Branch 1 not taken.
233 remove_lockblocks(screen_handles);
6509 233 }
6510
6511
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 45679 times.
45680 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6512 {
6513
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6514 1 }
6515
6516
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
✓ Branch 3 taken 45579 times.
45680 if(game->maps[mi]&mCHEST) // if special stuff done before
6517 {
6518
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 remove_chests(screen_handles);
6519 101 }
6520
6521
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 45656 times.
45680 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6522 {
6523
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 remove_lockedchests(screen_handles);
6524 24 }
6525
6526
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6527 {
6528 remove_bosschests(screen_handles);
6529 }
6530
6531
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xdoors(screen_handles);
6532
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xstatecombos(screen_handles);
6533
6534 // check doors
6535
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 45626 times.
45680 if (isdungeon(screen))
6536 {
6537
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 54 times.
270 for(int32_t i=0; i<4; i++)
6538 {
6539 216 int32_t door=scr->door[i];
6540 216 bool putit=true;
6541
6542
4/5
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 139 times.
216 switch(door)
6543 {
6544 case d1WAYSHUTTER:
6545 case dSHUTTER:
6546 61 break;
6547
6548 case dLOCKED:
6549
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(game->maps[mi]&(1<<i))
6550 {
6551 12 scr->door[i]=dUNLOCKED;
6552 12 }
6553
6554 12 break;
6555
6556 case dBOSS:
6557
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(game->maps[mi]&(1<<i))
6558 {
6559 scr->door[i]=dOPENBOSS;
6560 }
6561
6562 4 break;
6563
6564 case dBOMB:
6565 if(game->maps[mi]&(1<<i))
6566 {
6567 scr->door[i]=dBOMBED;
6568 }
6569
6570 break;
6571 }
6572
6573
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(putit)
6574 {
6575
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 putdoor(scr, scrollbuf, i, scr->door[i], false);
6576 216 }
6577
6578
3/4
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
216 if(door==dSHUTTER||door==d1WAYSHUTTER)
6579 {
6580 61 scr->door[i]=door;
6581 61 }
6582 216 }
6583 54 }
6584
6585
2/2
✓ Branch 0 taken 319760 times.
✓ Branch 1 taken 45680 times.
365440 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6586 {
6587
4/4
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
✓ Branch 2 taken 64814 times.
✓ Branch 3 taken 209266 times.
319760 if (j < 0 || scr->layermap[j] > 0)
6588 {
6589
2/2
✓ Branch 0 taken 64814 times.
✓ Branch 1 taken 45680 times.
110494 mapscr *layerscreen= (j<0 ? scr
6590 64814 : &(TheMaps[(scr->layermap[j]-1)*MAPSCRS+scr->layerscreen[j]]));
6591
6592
2/2
✓ Branch 0 taken 19446944 times.
✓ Branch 1 taken 110494 times.
19557438 for(int32_t i=0; i<176; ++i)
6593 {
6594 19446944 int32_t c=layerscreen->data[i];
6595
6596 // New screen flag: Cycle Combos At Screen Init
6597
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 19446944 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
19446944 if((scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6598 {
6599 int32_t r = 0;
6600
6601 while(combobuf[c].can_cycle() && r++ < 10)
6602 {
6603 newcombo const& cmb = combobuf[c];
6604 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6605 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6606 layerscreen->data[i] = cid;
6607 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6608 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6609 c = layerscreen->data[i];
6610 }
6611 }
6612 19446944 }
6613 110494 }
6614 319760 }
6615
6616 45680 return scrs;
6617
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 }
6618
6619 19001307 void putscr(mapscr* scr, BITMAP* dest, int32_t x, int32_t y)
6620 {
6621 // This is a bogus value while screenscrolling == true, but that's ok
6622 // because it is only used to calculate the rpos, and during screenscrolling
6623 // only the modulus to get pos (draw_cmb_pos does RPOS_TO_POS) is needed, which
6624 // is always the same no matter the value of scr.
6625 19001307 int screen = get_screen_for_world_xy(x, y);
6626
6627 19001307 x -= viewport.x;
6628 19001307 y -= viewport.y;
6629
6630
3/6
✓ Branch 0 taken 19001307 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19001307 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19001307 times.
19001307 if (!scr->is_valid()||!show_layers[0]||scr->hidelayers & 1)
6631 {
6632 rectfill(dest,x,y,x+255,y+175,0);
6633 return;
6634 }
6635
6636 37873704 bool over = XOR(scr->flags7&fLAYER2BG,DMaps[cur_dmap].flags&dmfLAYER2BG)
6637
2/2
✓ Branch 0 taken 128910 times.
✓ Branch 1 taken 18872397 times.
19001307 || XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG);
6638
6639 int start_x, end_x, start_y, end_y;
6640 19001307 get_bounds_for_draw_cmb_calls(dest, x, y, start_x, end_x, start_y, end_y);
6641
2/2
✓ Branch 0 taken 19001307 times.
✓ Branch 1 taken 202388759 times.
221390066 for (int cy = start_y; cy < end_y; cy++)
6642 {
6643
2/2
✓ Branch 0 taken 3073359042 times.
✓ Branch 1 taken 202388759 times.
3275747801 for (int cx = start_x; cx < end_x; cx++)
6644 {
6645 3073359042 int i = cx + cy*16;
6646
2/2
✓ Branch 0 taken 357691558 times.
✓ Branch 1 taken 2715667484 times.
3073359042 auto rpos = screenscrolling ? rpos_t::None : POS_TO_RPOS(i, screen);
6647 3073359042 draw_cmb_pos(dest, x + cx*16, y + cy*16, rpos, scr->data[i], scr->cset[i], 0, over, false);
6648 3073359042 }
6649 202388759 }
6650 19001307 }
6651
6652 15526581 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y)
6653 {
6654
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15526581 times.
15526581 if (!show_layers[0])
6655 {
6656 return;
6657 }
6658
6659 15526581 x -= viewport.x;
6660 15526581 y -= viewport.y;
6661
6662
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15526581 times.
31189480 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
6663 15662899 mapscr* scr = screen_handles[0].base_scr;
6664
1/2
✓ Branch 0 taken 15662899 times.
✗ Branch 1 not taken.
15662899 if (!scr->is_valid())
6665 return;
6666
6667
2/2
✓ Branch 0 taken 123411 times.
✓ Branch 1 taken 15539488 times.
15662899 if(scr->door[0]==dBOMBED)
6668 {
6669 123411 over_door(scr, dest, 39, up, offx+x, offy+y);
6670 123411 }
6671
6672
2/2
✓ Branch 0 taken 143109 times.
✓ Branch 1 taken 15519790 times.
15662899 if(scr->door[1]==dBOMBED)
6673 {
6674 143109 over_door(scr, dest, 135, down, offx+x, offy+y);
6675 143109 }
6676
6677
2/2
✓ Branch 0 taken 155862 times.
✓ Branch 1 taken 15507037 times.
15662899 if(scr->door[2]==dBOMBED)
6678 {
6679 155862 over_door(scr, dest, 66, left, offx+x, offy+y);
6680 155862 }
6681
6682
2/2
✓ Branch 0 taken 132289 times.
✓ Branch 1 taken 15530610 times.
15662899 if(scr->door[3]==dBOMBED)
6683 {
6684 132289 over_door(scr, dest, 77, right, offx+x, offy+y);
6685 132289 }
6686 15662899 });
6687 15526581 }
6688
6689 3338408 void putscrdoors(mapscr* scr, BITMAP *dest, int32_t x, int32_t y)
6690 {
6691
2/4
✓ Branch 0 taken 3338408 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3338408 times.
✗ Branch 3 not taken.
3338408 if (!scr->is_valid() || !show_layers[0])
6692 return;
6693
6694 3338408 x -= viewport.x;
6695 3338408 y -= viewport.y;
6696
6697
2/2
✓ Branch 0 taken 37656 times.
✓ Branch 1 taken 3300752 times.
3338408 if(scr->door[0]==dBOMBED)
6698 {
6699 37656 over_door(scr,dest,39,up,x,y);
6700 37656 }
6701
6702
2/2
✓ Branch 0 taken 36495 times.
✓ Branch 1 taken 3301913 times.
3338408 if(scr->door[1]==dBOMBED)
6703 {
6704 36495 over_door(scr,dest,135,down,x,y);
6705 36495 }
6706
6707
2/2
✓ Branch 0 taken 40440 times.
✓ Branch 1 taken 3297968 times.
3338408 if(scr->door[2]==dBOMBED)
6708 {
6709 40440 over_door(scr,dest,66,left,x,y);
6710 40440 }
6711
6712
2/2
✓ Branch 0 taken 37063 times.
✓ Branch 1 taken 3301345 times.
3338408 if(scr->door[3]==dBOMBED)
6713 {
6714 37063 over_door(scr,dest,77,right,x,y);
6715 37063 }
6716 3338408 }
6717 231354425 static inline bool onSwitch(newcombo const& cmb, zfix const& switchblockstate)
6718 {
6719
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 231354425 times.
✓ Branch 2 taken 231340696 times.
✓ Branch 3 taken 13729 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 13729 times.
231354425 return (switchblockstate < 0 || (cmb.attributes[2]>0 && (zslongToFix(cmb.attributes[2]) - zslongToFix(zc_max(cmb.attributes[3], 0))) <=switchblockstate));
6720 }
6721 55812276 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt)
6722 {
6723 55812276 return _walkflag(zx,zy,cnt,0_zf);
6724 }
6725
6726 132306538 bool _walkflag_new(const mapscr* s0, const mapscr* s1, const mapscr* s2, zfix_round zx, zfix_round zy, zfix const& switchblockstate, bool is_temp_screens)
6727 {
6728 132306538 int x = zx.getRound(), y = zy.getRound();
6729 132306538 int pos = COMBOPOS(x % 256, y % 176);
6730 132306538 const newcombo& c = combobuf[s0->data[pos]];
6731 132306538 const newcombo& c1 = combobuf[s1->data[pos]];
6732 132306538 const newcombo& c2 = combobuf[s2->data[pos]];
6733
4/4
✓ Branch 0 taken 130314083 times.
✓ Branch 1 taken 1992455 times.
✓ Branch 2 taken 130304623 times.
✓ Branch 3 taken 9460 times.
264815364 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6734
4/4
✓ Branch 0 taken 101153 times.
✓ Branch 1 taken 130405758 times.
✓ Branch 2 taken 2098823 times.
✓ Branch 3 taken 4245 times.
132306538 (iswater_type(c2.type))) && DRIEDLAKE);
6735 132508826 int32_t b=1;
6736
2/2
✓ Branch 0 taken 65319932 times.
✓ Branch 1 taken 67188894 times.
132508826 if(x&8) b<<=2;
6737
2/2
✓ Branch 0 taken 61875148 times.
✓ Branch 1 taken 70633678 times.
132508826 if(y&8) b<<=1;
6738
6739 132508826 int32_t cwalkflag = c.walk;
6740
3/8
✓ Branch 0 taken 132407682 times.
✓ Branch 1 taken 101144 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 132407682 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
132508826 if(is_temp_screens && onSwitch(c,switchblockstate) && c.type == cCSWITCHBLOCK && c.usrflags&cflag9) cwalkflag &= (c.walk>>4)^0xF;
6741
8/10
✓ Branch 0 taken 50572 times.
✓ Branch 1 taken 132458254 times.
✓ Branch 2 taken 2093599 times.
✓ Branch 3 taken 2043027 times.
✓ Branch 4 taken 2093599 times.
✓ Branch 5 taken 132407682 times.
✓ Branch 6 taken 2093599 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2093599 times.
✗ Branch 9 not taken.
132508826 else if ((c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) || (iswater_type(c.type) && ((c.walk>>4)&b) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6742
2/2
✓ Branch 0 taken 63161240 times.
✓ Branch 1 taken 69246442 times.
132407682 if (s1 != s0)
6743 {
6744
2/8
✓ Branch 0 taken 69246442 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 69246442 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
69246442 if(is_temp_screens && onSwitch(c1,switchblockstate) && c1.type == cCSWITCHBLOCK && c1.usrflags&cflag9) cwalkflag &= (c1.walk>>4)^0xF;
6745
4/10
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69234713 times.
✓ Branch 2 taken 11729 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11729 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
69246442 else if ((iswater_type(c1.type) && ((c1.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_1) && !((c1.usrflags&cflag3) || (c1.usrflags&cflag4)))) cwalkflag &= c1.walk;
6746
2/2
✓ Branch 0 taken 62906 times.
✓ Branch 1 taken 69183536 times.
69246442 else if (c1.type == cBRIDGE)
6747 {
6748
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62906 times.
62906 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6749 {
6750 62906 int efflag = (c1.walk & 0xF0)>>4;
6751 62906 int newsolid = (c1.walk & 0xF);
6752 62906 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6753 62906 }
6754 else cwalkflag &= c1.walk;
6755 62906 }
6756
3/8
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69171807 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11729 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
69183536 else if ((iswater_type(c1.type) && get_qr(qr_WATER_ON_LAYER_1) && ((c1.usrflags&cflag3) || (c1.usrflags&cflag4)) && ((c1.walk>>4)&b))) cwalkflag = 0;
6757 69183536 else cwalkflag |= c1.walk;
6758 69246442 }
6759
2/2
✓ Branch 0 taken 102707381 times.
✓ Branch 1 taken 29700301 times.
132407682 if (s2 != s0)
6760 {
6761
2/8
✓ Branch 0 taken 29700301 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 29700301 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
29700301 if(is_temp_screens && onSwitch(c2,switchblockstate) && c2.type == cCSWITCHBLOCK && c2.usrflags&cflag9) cwalkflag &= (c2.walk>>4)^0xF;
6762
4/10
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 29698147 times.
✓ Branch 2 taken 2154 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2154 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
29700301 else if ((iswater_type(c2.type) && ((c2.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_2) && !((c2.usrflags&cflag3) || (c2.usrflags&cflag4)))) cwalkflag &= c2.walk;
6763
2/2
✓ Branch 0 taken 1310 times.
✓ Branch 1 taken 29698991 times.
29700301 else if (c2.type == cBRIDGE)
6764 {
6765
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1310 times.
1310 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6766 {
6767 1310 int efflag = (c2.walk & 0xF0)>>4;
6768 1310 int newsolid = (c2.walk & 0xF);
6769 1310 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6770 1310 }
6771 else cwalkflag &= c2.walk;
6772 1310 }
6773
3/8
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 29696837 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2154 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
29698991 else if ((iswater_type(c2.type) && get_qr(qr_WATER_ON_LAYER_2) && ((c2.usrflags&cflag3) || (c2.usrflags&cflag4))) && ((c2.walk>>4)&b)) cwalkflag = 0;
6774 29698991 else cwalkflag |= c2.walk;
6775 29700301 }
6776
6777
4/4
✓ Branch 0 taken 29538102 times.
✓ Branch 1 taken 102869580 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 29537154 times.
132407682 if((cwalkflag&b) && !dried)
6778 29537154 return true;
6779
6780
3/4
✓ Branch 0 taken 102870528 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 102854117 times.
✓ Branch 3 taken 16411 times.
102870528 if (is_temp_screens && collide_object(zx, zy, 0.0001_zf, 0.0001_zf)) return true;
6781
6782 102854117 return false;
6783 132407682 }
6784
6785 // Returns true if the combo at viewport position x,y is solid. Looks at a combo's quadrant walkablity flags.
6786 132407682 static bool _walkflag_new(zfix_round zx, zfix_round zy, zfix const& switchblockstate)
6787 {
6788 132407682 int x = zx.getRound(), y = zy.getRound();
6789 132407682 mapscr* s0 = get_scr_for_world_xy_layer(x, y, 0);
6790 132407682 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6791 132407682 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6792
2/2
✓ Branch 0 taken 63161240 times.
✓ Branch 1 taken 69246442 times.
132407682 if (!s1->valid) s1 = s0;
6793
2/2
✓ Branch 0 taken 102707381 times.
✓ Branch 1 taken 29700301 times.
132407682 if (!s2->valid) s2 = s0;
6794 132407682 return _walkflag_new(s0, s1, s2, zx, zy, switchblockstate, true);
6795 }
6796
6797 128204686 bool _walkflag(zfix_round x,zfix_round y,int32_t cnt,zfix const& switchblockstate)
6798 {
6799 128204686 int max_x = world_w;
6800 128204686 int max_y = world_h;
6801
2/2
✓ Branch 0 taken 68297999 times.
✓ Branch 1 taken 59906687 times.
128204686 if (!get_qr(qr_LTTPWALK))
6802 {
6803 59906687 max_x -= 7;
6804 59906687 max_y -= 7;
6805 59906687 }
6806
4/4
✓ Branch 0 taken 127933866 times.
✓ Branch 1 taken 270820 times.
✓ Branch 2 taken 83268 times.
✓ Branch 3 taken 127850598 times.
128204686 if (x < 0 || y < 0) return false;
6807
2/2
✓ Branch 0 taken 322238 times.
✓ Branch 1 taken 127528360 times.
127850598 if (x >= max_x) return false;
6808
3/4
✓ Branch 0 taken 539458 times.
✓ Branch 1 taken 126988902 times.
✓ Branch 2 taken 539458 times.
✗ Branch 3 not taken.
127528360 if (x >= max_x - 8 && cnt == 2) return false;
6809
2/2
✓ Branch 0 taken 126979158 times.
✓ Branch 1 taken 549202 times.
127528360 if (y >= max_y) return false;
6810
6811
4/4
✓ Branch 0 taken 29435405 times.
✓ Branch 1 taken 97543753 times.
✓ Branch 2 taken 92115229 times.
✓ Branch 3 taken 5428524 times.
126979158 return _walkflag_new(x, y, switchblockstate) || (cnt != 1 && _walkflag_new(x + 8, y, switchblockstate));
6812 128204686 }
6813
6814 99017955 static bool effectflag(int32_t x, int32_t y, int32_t layer)
6815 {
6816 99017955 mapscr* s0 = get_scr_for_world_xy(x, y);
6817 99017955 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6818 99017955 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6819
2/2
✓ Branch 0 taken 51391831 times.
✓ Branch 1 taken 47626124 times.
99017955 if (!s1->valid) s1 = s0;
6820
2/2
✓ Branch 0 taken 17530096 times.
✓ Branch 1 taken 81487859 times.
99017955 if (!s2->valid) s2 = s0;
6821
6822 99017955 int pos = COMBOPOS(x % 256, y % 176);
6823 99017955 const newcombo& c = combobuf[s0->data[pos]];
6824 99017955 const newcombo& c1 = combobuf[s1->data[pos]];
6825 99017955 const newcombo& c2 = combobuf[s2->data[pos]];
6826
4/4
✓ Branch 0 taken 98090677 times.
✓ Branch 1 taken 927278 times.
✓ Branch 2 taken 98089311 times.
✓ Branch 3 taken 1366 times.
198035910 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6827
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 98089311 times.
✓ Branch 2 taken 926808 times.
✓ Branch 3 taken 1836 times.
99017955 (iswater_type(c2.type))) && DRIEDLAKE);
6828 99017955 int32_t b=1;
6829
2/2
✓ Branch 0 taken 49817649 times.
✓ Branch 1 taken 49200306 times.
99017955 if(x&8) b<<=2;
6830
2/2
✓ Branch 0 taken 41760540 times.
✓ Branch 1 taken 57257415 times.
99017955 if(y&8) b<<=1;
6831
6832 99017955 int32_t cwalkflag = (c.walk>>4);
6833
2/2
✓ Branch 0 taken 76265628 times.
✓ Branch 1 taken 22752327 times.
99017955 if (layer == 0) cwalkflag = (c1.walk>>4);
6834
2/2
✓ Branch 0 taken 76266616 times.
✓ Branch 1 taken 22751339 times.
99017955 if (layer == 1) cwalkflag = (c2.walk>>4);
6835 //if (c.type == cBRIDGE || (iswater_type(c.type) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6836
4/4
✓ Branch 0 taken 51391831 times.
✓ Branch 1 taken 47626124 times.
✓ Branch 2 taken 22423002 times.
✓ Branch 3 taken 28968829 times.
99017955 if (s1 != s0 && layer < 0)
6837 {
6838
2/2
✓ Branch 0 taken 22409596 times.
✓ Branch 1 taken 13406 times.
22423002 if (c1.type == cBRIDGE) cwalkflag &= (~(c1.walk>>4));
6839 22423002 }
6840
4/4
✓ Branch 0 taken 17530096 times.
✓ Branch 1 taken 81487859 times.
✓ Branch 2 taken 13009719 times.
✓ Branch 3 taken 4520377 times.
99017955 if (s2 != s0 && layer < 1)
6841 {
6842
2/2
✓ Branch 0 taken 13009367 times.
✓ Branch 1 taken 352 times.
13009719 if (c2.type == cBRIDGE) cwalkflag &= (~(c2.walk>>4));
6843 13009719 }
6844
6845
2/2
✓ Branch 0 taken 98864209 times.
✓ Branch 1 taken 153746 times.
99017955 return (cwalkflag&b) ? !dried : false;
6846 }
6847
6848 99392839 bool _effectflag(int32_t x,int32_t y,int32_t cnt, int32_t layer, bool notLink)
6849 {
6850 DCHECK(cnt == 0 || cnt == 1);
6851 99392839 int max_x = world_w;
6852 99392839 int max_y = world_h;
6853
3/4
✓ Branch 0 taken 45832191 times.
✓ Branch 1 taken 53560648 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45832191 times.
99392839 if (!get_qr(qr_LTTPWALK) && !notLink)
6854 {
6855 45832191 max_x -= 7;
6856 45832191 max_y -= 7;
6857 45832191 }
6858
4/4
✓ Branch 0 taken 99392086 times.
✓ Branch 1 taken 753 times.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 99391882 times.
99392839 if (x < 0 || y < 0) return false;
6859
2/2
✓ Branch 0 taken 818 times.
✓ Branch 1 taken 99391064 times.
99391882 if (x >= max_x) return false;
6860
3/4
✓ Branch 0 taken 521750 times.
✓ Branch 1 taken 98869314 times.
✓ Branch 2 taken 521750 times.
✗ Branch 3 not taken.
99391064 if (x >= max_x - 8 && cnt == 2) return false;
6861
2/2
✓ Branch 0 taken 373109 times.
✓ Branch 1 taken 99017955 times.
99391064 if (y >= max_y) return false;
6862
6863
3/4
✓ Branch 0 taken 98863419 times.
✓ Branch 1 taken 154536 times.
✓ Branch 2 taken 154536 times.
✗ Branch 3 not taken.
99017955 return effectflag(x, y, layer) || (cnt == 2 && effectflag(x + 8, y, layer));
6864 99392839 }
6865
6866 // used by mapdata->isSolid(x,y) in ZScript
6867 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
6868 {
6869 int x = zx.getRound(), y = zy.getRound();
6870 {
6871 int max_x = 256;
6872 int max_y = 176;
6873 if (!get_qr(qr_LTTPWALK))
6874 {
6875 max_x -= 7;
6876 max_y -= 7;
6877 }
6878 if (x < 0 || y < 0) return false;
6879 if (x >= max_x) return false;
6880 if (x >= max_x - 8 && cnt == 2) return false;
6881 if (y >= max_y) return false;
6882 }
6883
6884 const mapscr *s1, *s2;
6885
6886 if ( m->layermap[0] > 0 )
6887 {
6888 s1 = get_canonical_scr(m->layermap[0], m->layerscreen[0]);
6889 }
6890 else s1 = m;
6891
6892 if ( m->layermap[1] > 0 )
6893 {
6894 s2 = get_canonical_scr(m->layermap[1], m->layerscreen[1]);
6895 }
6896 else s2 = m;
6897
6898 zfix unused;
6899 return _walkflag_new(m, s1, s2, x, y, unused, false) || (cnt != 1 && _walkflag_new(m, s1, s2, x + 8, y, unused, false));
6900 }
6901
6902 bool _walkflag_layer(zfix_round x, zfix_round y, int32_t layer, int32_t cnt)
6903 {
6904 DCHECK_LAYER_NEG1_INDEX(layer);
6905 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
6906 if (!m->is_valid()) return false;
6907 return _walkflag_layer(x, y, cnt, m);
6908 }
6909
6910 static bool _walkflag_layer_new(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m, int max_x, int max_y)
6911 {
6912 int x = zx.getRound(), y = zy.getRound();
6913
6914 if (!get_qr(qr_LTTPWALK))
6915 {
6916 max_x -= 7;
6917 max_y -= 7;
6918 }
6919 if (x < 0 || y < 0) return false;
6920 if (x >= max_x) return false;
6921 if (x >= max_x - 8 && cnt == 2) return false;
6922 if (y >= max_y) return false;
6923
6924 if(!m) return true;
6925
6926 int pos = COMBOPOS(x%256, y%176);
6927 const newcombo* c = &combobuf[m->data[pos]];
6928 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
6929 int32_t b=1;
6930
6931 if(x&8) b<<=2;
6932
6933 if(y&8) b<<=1;
6934
6935 if((c->walk&b) && !dried)
6936 return true;
6937
6938 if(cnt==1) return false;
6939
6940 ++pos;
6941
6942 if(!(x&8))
6943 b<<=2;
6944 else
6945 {
6946 c = &combobuf[m->data[pos]];
6947 dried = ((iswater_type(c->type)) && DRIEDLAKE);
6948 b=1;
6949
6950 if(y&8) b<<=1;
6951 }
6952
6953 return (c->walk&b) ? !dried : false;
6954 }
6955
6956 //Only check the given mapscr*, not its layer 1&2
6957 bool _walkflag_layer(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
6958 {
6959 return _walkflag_layer_new(zx, zy, cnt, m, world_w, world_h);
6960 }
6961
6962 bool _walkflag_layer_scrolling(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
6963 {
6964 return _walkflag_layer_new(zx, zy, cnt, m, scrolling_region.width, scrolling_region.height);
6965 }
6966
6967 261239 bool _effectflag_layer(int32_t x, int32_t y, int32_t layer, int32_t cnt, bool notLink)
6968 {
6969 DCHECK_LAYER_NEG1_INDEX(layer);
6970 261239 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
6971
2/2
✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 259477 times.
261239 if (!m->is_valid()) return false;
6972 259477 return _effectflag_layer(x, y, cnt, m, notLink);
6973 261239 }
6974
6975 322275 bool _effectflag_layer(int32_t x,int32_t y,int32_t cnt, mapscr* m, bool notLink)
6976 {
6977 322275 int max_x = world_w;
6978 322275 int max_y = world_h;
6979
3/4
✓ Branch 0 taken 50002 times.
✓ Branch 1 taken 272273 times.
✓ Branch 2 taken 50002 times.
✗ Branch 3 not taken.
322275 if (!get_qr(qr_LTTPWALK) && !notLink)
6980 {
6981 max_x -= 7;
6982 max_y -= 7;
6983 }
6984
2/4
✓ Branch 0 taken 322275 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 322275 times.
322275 if (x < 0 || y < 0) return false;
6985
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 322275 times.
322275 if (x >= max_x) return false;
6986
3/4
✓ Branch 0 taken 1209 times.
✓ Branch 1 taken 321066 times.
✓ Branch 2 taken 1209 times.
✗ Branch 3 not taken.
322275 if (x >= max_x - 8 && cnt == 2) return false;
6987
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 322275 times.
322275 if (y >= max_y) return false;
6988
6989
1/2
✓ Branch 0 taken 322275 times.
✗ Branch 1 not taken.
322275 if (!m) return true;
6990
6991 322275 int pos = COMBOPOS(x%256, y%176);
6992 322275 const newcombo* c = &combobuf[m->data[pos]];
6993
3/4
✓ Branch 0 taken 321894 times.
✓ Branch 1 taken 381 times.
✓ Branch 2 taken 381 times.
✗ Branch 3 not taken.
322656 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
6994 322275 int32_t b=1;
6995
6996
2/2
✓ Branch 0 taken 178894 times.
✓ Branch 1 taken 143381 times.
322275 if(x&8) b<<=2;
6997
6998
2/2
✓ Branch 0 taken 135815 times.
✓ Branch 1 taken 186460 times.
322275 if(y&8) b<<=1;
6999
7000
3/4
✓ Branch 0 taken 253281 times.
✓ Branch 1 taken 68994 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 253281 times.
322275 if(((c->walk>>4)&b) && !dried)
7001 253281 return true;
7002
7003
1/2
✓ Branch 0 taken 68994 times.
✗ Branch 1 not taken.
68994 if(cnt==1) return false;
7004
7005 ++pos;
7006
7007 if(!(x&8))
7008 b<<=2;
7009 else
7010 {
7011 c = &combobuf[m->data[pos]];
7012 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7013 b=1;
7014
7015 if(y&8) b<<=1;
7016 }
7017
7018 return ((c->walk>>4)&b) ? !dried : false;
7019 322275 }
7020
7021 812605 bool water_walkflag(int32_t x, int32_t y, int32_t cnt)
7022 {
7023 812605 int max_x = world_w;
7024 812605 int max_y = world_h;
7025
2/2
✓ Branch 0 taken 117367 times.
✓ Branch 1 taken 695238 times.
812605 if (!get_qr(qr_LTTPWALK))
7026 {
7027 695238 max_x -= 7;
7028 695238 max_y -= 7;
7029 695238 }
7030
2/4
✓ Branch 0 taken 812605 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 812605 times.
812605 if (x < 0 || y < 0) return false;
7031
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (x >= max_x) return false;
7032
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
812605 if (x >= max_x - 8 && cnt == 2) return false;
7033
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (y >= max_y) return false;
7034
7035
3/4
✓ Branch 0 taken 16825 times.
✓ Branch 1 taken 795780 times.
✓ Branch 2 taken 795780 times.
✗ Branch 3 not taken.
812605 return water_walkflag(x, y) || (cnt != 1 && water_walkflag(x + 8, y));
7036 812605 }
7037
7038 812605 bool water_walkflag(int32_t x, int32_t y)
7039 {
7040 812605 const newcombo& c = combobuf[MAPCOMBO2(-1, x, y)];
7041 812605 const newcombo& c1 = combobuf[MAPCOMBO2(0, x, y)];
7042 812605 const newcombo& c2 = combobuf[MAPCOMBO2(1, x, y)];
7043
7044 812605 int32_t b=1;
7045
2/2
✓ Branch 0 taken 414677 times.
✓ Branch 1 taken 397928 times.
812605 if(x&8) b<<=2;
7046
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if(y&8) b<<=1;
7047
7048
2/2
✓ Branch 0 taken 26377 times.
✓ Branch 1 taken 786228 times.
812605 if(get_qr(qr_NO_SOLID_SWIM))
7049 {
7050
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 26245 times.
26377 if(c.walk&b)
7051 132 return true;
7052
7053
2/2
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 25953 times.
26245 if(c1.walk&b)
7054 292 return true;
7055
7056
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25953 times.
25953 if(c2.walk&b)
7057 return true;
7058 25953 }
7059 else
7060 {
7061
4/4
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 750095 times.
✓ Branch 2 taken 19762 times.
✓ Branch 3 taken 16371 times.
786228 if((c.walk&b) && !iswater_type(c.type))
7062 16371 return true;
7063
7064
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 769840 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
769857 if((c1.walk&b) && !iswater_type(c1.type))
7065 17 return true;
7066
7067
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 769827 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
769840 if((c2.walk&b) && !iswater_type(c2.type))
7068 13 return true;
7069 }
7070
7071 795780 return false;
7072 812605 }
7073
7074 563892 bool hit_walkflag(int32_t x,int32_t y,int32_t cnt)
7075 {
7076
2/2
✓ Branch 0 taken 90807 times.
✓ Branch 1 taken 473085 times.
563892 if(dlevel)
7077
8/8
✓ Branch 0 taken 471680 times.
✓ Branch 1 taken 1405 times.
✓ Branch 2 taken 468485 times.
✓ Branch 3 taken 3195 times.
✓ Branch 4 taken 466825 times.
✓ Branch 5 taken 1660 times.
✓ Branch 6 taken 4199 times.
✓ Branch 7 taken 462626 times.
473085 if(x<32 || y<40 || (x+(cnt-1)*8)>=world_w-32 || y>=world_h-32)
7078 10459 return true;
7079
7080
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 553431 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
553433 if(blockpath && y<((get_qr(qr_LTTPCOLLISION))?80:88))
7081 return true;
7082
7083
8/8
✓ Branch 0 taken 553164 times.
✓ Branch 1 taken 269 times.
✓ Branch 2 taken 552931 times.
✓ Branch 3 taken 233 times.
✓ Branch 4 taken 552722 times.
✓ Branch 5 taken 209 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 552376 times.
553433 if(x<16 || y<16 || (x+(cnt-1)*8)>=world_w-16 || y>=world_h-16)
7084 1057 return true;
7085
7086 // for(int32_t i=0; i<4; i++)
7087
4/4
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 551535 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 805 times.
552376 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7088 36 return true;
7089
7090
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 552340 times.
552340 if (collide_object(x, y,cnt*8, 1))
7091 return true;
7092
7093 552340 return _walkflag(x,y,cnt);
7094 563892 }
7095
7096 12110 bool solpush_walkflag(int32_t x, int32_t y, int32_t cnt, solid_object const* ign)
7097 {
7098 // 16 pixel buffer to account for slopes that are on bordering screens.
7099
4/8
✓ Branch 0 taken 12110 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12110 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12110 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12110 times.
12110 if(x<0 || y<0 || x>=world_w+16 || y>=world_h+16)
7100 return true;
7101
7102 // for(int32_t i=0; i<4; i++)
7103
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12110 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7104 return true;
7105
7106
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
12110 if (collide_object(x, y,cnt*8, 1, ign))
7107 return true;
7108
7109 12110 return _walkflag(x,y,cnt);
7110 12110 }
7111
7112 37813 void map_bkgsfx(bool on)
7113 {
7114
2/2
✓ Branch 0 taken 37792 times.
✓ Branch 1 taken 21 times.
37813 if(on)
7115 {
7116 37792 cont_sfx(hero_scr->oceansfx);
7117
7118
4/4
✓ Branch 0 taken 369 times.
✓ Branch 1 taken 37423 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 54 times.
37792 if(hero_scr->bosssfx && !(game->lvlitems[dlevel]&liBOSS))
7119 315 cont_sfx(hero_scr->bosssfx);
7120 37792 }
7121 else
7122 {
7123 21 adjust_sfx(hero_scr->oceansfx,128,false);
7124 21 adjust_sfx(hero_scr->bosssfx,128,false);
7125
7126
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 21 times.
135 for(int32_t i=0; i<guys.Count(); i++)
7127 {
7128
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 84 times.
114 if(((enemy*)guys.spr(i))->bgsfx)
7129 84 stop_sfx(((enemy*)guys.spr(i))->bgsfx);
7130 114 }
7131 }
7132 37813 }
7133
7134 239 void toggle_switches(dword flags, bool entry)
7135 {
7136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 239 times.
239 if(!flags) return; //No flags to toggle
7137
7138 478 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7139 239 toggle_switches(flags, entry, create_screen_handles(scr));
7140 239 });
7141 239 }
7142 54016 void toggle_switches(dword flags, bool entry, const screen_handles_t& screen_handles)
7143 {
7144
2/2
✓ Branch 0 taken 737 times.
✓ Branch 1 taken 53279 times.
54016 if(!flags) return; //No flags to toggle
7145
7146 737 mapscr* m = screen_handles[0].base_scr;
7147 737 int screen = m->screen;
7148 737 bool is_active_screen = is_in_current_region(m);
7149
7150 305041 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
7151 304304 byte togglegrid[176] = {0};
7152 304304 mapscr* scr = rpos_handle.scr;
7153 304304 int lyr = rpos_handle.layer;
7154 304304 int pos = rpos_handle.pos;
7155 304304 newcombo const& cmb = combobuf[scr->data[pos]];
7156
2/2
✓ Branch 0 taken 39424 times.
✓ Branch 1 taken 264880 times.
304304 if(is_active_screen)
7157
2/2
✓ Branch 0 taken 264880 times.
✓ Branch 1 taken 102893 times.
367773 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
7158 {
7159 102893 auto& trig = cmb.triggers[idx];
7160
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 102893 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
102893 if((trig.triggerflags[3] & combotriggerTRIGLEVELSTATE) && trig.trig_lstate < 32)
7161 if(flags&(1<<trig.trig_lstate))
7162 {
7163 auto oldcombo = rpos_handle.data();
7164 do_trigger_combo(rpos_handle, idx, ctrigSWITCHSTATE);
7165 if(rpos_handle.data() != oldcombo) break;
7166 }
7167 367773 }
7168
3/4
✓ Branch 0 taken 303641 times.
✓ Branch 1 taken 663 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2760 times.
304304 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32
7169
2/2
✓ Branch 0 taken 2760 times.
✓ Branch 1 taken 301544 times.
304304 && !(cmb.usrflags & cflag11)) //global state
7170 {
7171
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2314 times.
2760 if(flags&(1<<cmb.attribytes[0]))
7172 {
7173 2314 set<int32_t> oldData;
7174 //Increment the combo/cset by the attributes
7175 2314 int32_t cmbofs = (cmb.attributes[0]/10000L);
7176 2314 int32_t csofs = (cmb.attributes[1]/10000L);
7177
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 oldData.insert(scr->data[pos]);
7178
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7179 2314 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7180
4/4
✓ Branch 0 taken 1435 times.
✓ Branch 1 taken 879 times.
✓ Branch 2 taken 1197 times.
✓ Branch 3 taken 238 times.
2314 if(entry && (cmb.usrflags&cflag8))
7181 {
7182 238 newcombo const* tmp = &combobuf[scr->data[pos]];
7183
2/4
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
238 while(tmp->can_cycle())
7184 {
7185 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7186 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7187 if(oldData.find(cid) != oldData.end())
7188 break;
7189
7190 scr->data[pos] = cid;
7191 if(!(tmp->animflags & AF_CYCLENOCSET))
7192 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7193 oldData.insert(cid);
7194 tmp = &combobuf[cid];
7195 }
7196 238 }
7197 2314 int32_t cmbid = scr->data[pos];
7198
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2273 times.
2314 if(combobuf[cmbid].animflags & AF_CYCLE)
7199 {
7200 41 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7201 41 combobuf[cmbid].cur_frame=0;
7202 41 combobuf[cmbid].aclk = 0;
7203
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 combo_caches::drawing.refresh(cmbid);
7204 41 }
7205 2314 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7206
2/2
✓ Branch 0 taken 511 times.
✓ Branch 1 taken 1803 times.
2314 if(cmb.type == cCSWITCH) return; //Switches don't toggle other layers
7207
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2147 times.
2147 for(int32_t lyr2 = 0; lyr2 < 7; ++lyr2) //Toggle same pos on other layers, if flag set
7208 {
7209
2/2
✓ Branch 0 taken 1671 times.
✓ Branch 1 taken 476 times.
2147 if(lyr==lyr2) return;
7210
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 344 times.
476 if(!(cmb.usrflags&(1<<lyr2))) return;
7211
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(togglegrid[pos]&(1<<lyr2)) return;
7212
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
344 mapscr* scr_2 = (lyr2 ? get_scr_layer(screen, lyr2) : m);
7213
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(!scr_2->data[pos]) //Don't increment empty space
7214 return;
7215 344 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7216
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
344 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK) && !(cmb.usrflags & cflag11)
7217 && cmb_2.attribytes[0] < 32 && (flags&(1<<cmb_2.attribytes[0])))
7218 return; //This is a switch/block that will be hit later in the loop!
7219 344 set<int32_t> oldData2;
7220 //Increment the combo/cset by the original cmb's attributes
7221
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 oldData2.insert(scr_2->data[pos]);
7222
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7223 344 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7224
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
344 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7225 {
7226 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7227 while(tmp->can_cycle())
7228 {
7229 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7230 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7231 if(oldData2.find(cid) != oldData2.end())
7232 break;
7233
7234 scr_2->data[pos] = cid;
7235 if(!(tmp->animflags & AF_CYCLENOCSET))
7236 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7237 oldData2.insert(cid);
7238 tmp = &combobuf[cid];
7239 }
7240 }
7241 344 int32_t cmbid2 = scr_2->data[pos];
7242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(combobuf[cmbid2].animflags & AF_CYCLE)
7243 {
7244 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7245 combobuf[cmbid2].cur_frame=0;
7246 combobuf[cmbid2].aclk = 0;
7247 combo_caches::drawing.refresh(cmbid2);
7248 }
7249 344 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7250 344 }
7251
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 2314 times.
✗ Branch 2 not taken.
2314 }
7252 446 }
7253 304304 });
7254
7255
3/4
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 218 times.
✓ Branch 2 taken 519 times.
✗ Branch 3 not taken.
737 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7256 {
7257 newcombo const& cmb = combobuf[mblock2.bcombo];
7258 if(!(cmb.usrflags & cflag11) && (cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32)
7259 {
7260 if(flags&(1<<cmb.attribytes[0]))
7261 {
7262 //Increment the combo/cset by the attributes
7263 int32_t cmbofs = (cmb.attributes[0]/10000L);
7264 int32_t csofs = (cmb.attributes[1]/10000L);
7265 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7266 mblock2.cs = (mblock2.cs + csofs) & 15;
7267 int32_t cmbid = mblock2.bcombo;
7268 if(combobuf[cmbid].animflags & AF_CYCLE)
7269 {
7270 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7271 combobuf[cmbid].cur_frame=0;
7272 combobuf[cmbid].aclk = 0;
7273 combo_caches::drawing.refresh(cmbid);
7274 }
7275 }
7276 }
7277 }
7278
7279
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 513 times.
737 if (is_active_screen)
7280 {
7281 513 int screen_index_offset = get_region_screen_offset(m->screen);
7282 513 word c = m->numFFC();
7283
2/2
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 513 times.
847 for (int q = 0; q < c; ++q)
7284 {
7285 334 auto ffc_handle = *m->getFFCHandle(q, screen_index_offset);
7286 334 auto& cmb = ffc_handle.combo();
7287
2/2
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 29 times.
363 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
7288 {
7289 29 auto& trig = cmb.triggers[idx];
7290
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
29 if((trig.triggerflags[3] & combotriggerTRIGLEVELSTATE) && trig.trig_lstate < 32)
7291 if(flags&(1<<trig.trig_lstate))
7292 {
7293 auto oldcombo = ffc_handle.data();
7294 do_trigger_combo(ffc_handle, idx, ctrigSWITCHSTATE);
7295 if(ffc_handle.data() != oldcombo) break;
7296 }
7297 29 }
7298 334 }
7299 513 }
7300 54016 }
7301
7302 void toggle_gswitches(int32_t state, bool entry)
7303 {
7304 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7305 toggle_gswitches(state, entry, create_screen_handles(scr));
7306 });
7307 }
7308 void toggle_gswitches(int32_t state, bool entry, const screen_handles_t& screen_handles)
7309 {
7310 bool states[256] = {false};
7311 states[state] = true;
7312 toggle_gswitches(states, entry, screen_handles);
7313 }
7314 15204141 void toggle_gswitches(bool* states, bool entry, const screen_handles_t& screen_handles)
7315 {
7316
1/2
✓ Branch 0 taken 15204141 times.
✗ Branch 1 not taken.
15204141 if(!states) return;
7317
7318 15204141 auto& combo_cache = combo_caches::gswitch;
7319 15204141 mapscr* base_scr = screen_handles[0].base_scr;
7320 15204141 int screen = base_scr->screen;
7321 15204141 bool is_active_screen = is_in_current_region(base_scr);
7322 15204141 byte togglegrid[176] = {0};
7323
2/2
✓ Branch 0 taken 15204141 times.
✓ Branch 1 taken 106428987 times.
121633128 for(int32_t lyr = 0; lyr <= 6; ++lyr)
7324 {
7325 106428987 mapscr* scr = screen_handles[lyr].scr;
7326
2/2
✓ Branch 0 taken 74161861 times.
✓ Branch 1 taken 32267126 times.
106428987 if (!scr)
7327 74161861 continue;
7328
7329
2/2
✓ Branch 0 taken 5679014176 times.
✓ Branch 1 taken 32267126 times.
5711281302 for(int32_t pos = 0; pos < 176; ++pos)
7330 {
7331 5679014176 int cid = scr->data[pos];
7332 5679014176 auto& mini_cmb = combo_cache.minis[cid];
7333
7334
2/2
✓ Branch 0 taken 93474656 times.
✓ Branch 1 taken 5585539520 times.
5679014176 if (is_active_screen)
7335 {
7336
2/2
✓ Branch 0 taken 5585537638 times.
✓ Branch 1 taken 1882 times.
5585539520 if (mini_cmb.trigger_global_state)
7337 {
7338 1882 auto& cmb = combobuf[cid];
7339
2/2
✓ Branch 0 taken 1882 times.
✓ Branch 1 taken 1882 times.
3764 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
7340 {
7341 1882 auto& trig = cmb.triggers[idx];
7342
2/4
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1882 times.
✗ Branch 3 not taken.
1882 if ((trig.triggerflags[3] & combotriggerTRIGGLOBALSTATE) && states[trig.trig_gstate])
7343 {
7344 auto rpos_handle = get_rpos_handle_for_screen(screen, lyr, pos);
7345 do_trigger_combo(rpos_handle, idx, ctrigSWITCHSTATE);
7346 if(rpos_handle.data() != cid) break;
7347 }
7348 1882 }
7349 1882 }
7350 5585539520 }
7351
7352
2/2
✓ Branch 0 taken 40395 times.
✓ Branch 1 taken 5678973781 times.
5679014176 if (!mini_cmb.has_global_state)
7353 5678973781 continue;
7354
7355 40395 newcombo const& cmb = combobuf[cid];
7356
2/4
✓ Branch 0 taken 40395 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40395 times.
40395 if(cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK)
7357 {
7358 if(states[cmb.attribytes[0]])
7359 {
7360 set<int32_t> oldData;
7361 //Increment the combo/cset by the attributes
7362 int32_t cmbofs = (cmb.attributes[0]/10000L);
7363 int32_t csofs = (cmb.attributes[1]/10000L);
7364 oldData.insert(scr->data[pos]);
7365 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7366 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7367 if(entry && (cmb.usrflags&cflag8))
7368 {
7369 newcombo const* tmp = &combobuf[scr->data[pos]];
7370 while(tmp->can_cycle())
7371 {
7372 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7373 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7374 if(oldData.find(cid) != oldData.end())
7375 break;
7376 scr->data[pos] = cid;
7377 if(!(tmp->animflags & AF_CYCLENOCSET))
7378 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7379 oldData.insert(cid);
7380 tmp = &combobuf[cid];
7381 }
7382 }
7383 int32_t cmbid = scr->data[pos];
7384 if(combobuf[cmbid].animflags & AF_CYCLE)
7385 {
7386 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7387 combobuf[cmbid].cur_frame=0;
7388 combobuf[cmbid].aclk = 0;
7389 combo_caches::drawing.refresh(cmbid);
7390 }
7391 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7392 if(cmb.type == cCSWITCH) continue; //Switches don't toggle other layers
7393 for(int32_t lyr2 = 0; lyr2 <= 6; ++lyr2) //Toggle same pos on other layers, if flag set
7394 {
7395 if(lyr==lyr2) continue;
7396 if(!(cmb.usrflags&(1<<lyr2))) continue;
7397 if(togglegrid[pos]&(1<<lyr2)) continue;
7398 mapscr* scr_2 = lyr2 == 0 ? base_scr : get_scr_layer_valid(screen, lyr2);
7399 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7400 continue;
7401 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7402 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK)
7403 && (cmb_2.usrflags & cflag11) && (states[cmb_2.attribytes[0]]))
7404 continue; //This is a switch/block that will be hit later in the loop!
7405 set<int32_t> oldData2;
7406 //Increment the combo/cset by the original cmb's attributes
7407 oldData2.insert(scr_2->data[pos]);
7408 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7409 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7410 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7411 {
7412 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7413 while(tmp->can_cycle())
7414 {
7415 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7416 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7417 if(oldData2.find(cid) != oldData2.end())
7418 break;
7419 scr_2->data[pos] = cid;
7420 if(!(tmp->animflags & AF_CYCLENOCSET))
7421 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7422 oldData2.insert(cid);
7423 tmp = &combobuf[cid];
7424 }
7425 }
7426 int32_t cmbid2 = scr_2->data[pos];
7427 if(combobuf[cmbid2].animflags & AF_CYCLE)
7428 {
7429 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7430 combobuf[cmbid2].cur_frame=0;
7431 combobuf[cmbid2].aclk = 0;
7432 combo_caches::drawing.refresh(cmbid2);
7433 }
7434 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7435 }
7436 }
7437 }
7438 40395 }
7439 32267126 }
7440
7441
4/4
✓ Branch 0 taken 535280 times.
✓ Branch 1 taken 14668861 times.
✓ Branch 2 taken 4744 times.
✓ Branch 3 taken 530536 times.
15204141 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7442 {
7443 4744 newcombo const& cmb = combobuf[mblock2.bcombo];
7444
2/4
✓ Branch 0 taken 4744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4744 times.
✗ Branch 3 not taken.
4744 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && (cmb.usrflags & cflag11))
7445 {
7446 if(states[cmb.attribytes[0]])
7447 {
7448 //Increment the combo/cset by the attributes
7449 int32_t cmbofs = (cmb.attributes[0]/10000L);
7450 int32_t csofs = (cmb.attributes[1]/10000L);
7451 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7452 mblock2.cs = (mblock2.cs + csofs) & 15;
7453 int32_t cmbid = mblock2.bcombo;
7454 if(combobuf[cmbid].animflags & AF_CYCLE)
7455 {
7456 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7457 combobuf[cmbid].cur_frame=0;
7458 combobuf[cmbid].aclk = 0;
7459 combo_caches::drawing.refresh(cmbid);
7460 }
7461 }
7462 }
7463 4744 }
7464
7465
2/2
✓ Branch 0 taken 413475 times.
✓ Branch 1 taken 14790666 times.
15204141 if(is_active_screen)
7466 {
7467 14790666 int screen_index_offset = get_region_screen_offset(screen);
7468 14790666 word c = base_scr->numFFC();
7469
2/2
✓ Branch 0 taken 441779442 times.
✓ Branch 1 taken 14790666 times.
456570108 for (int q = 0; q < c; ++q)
7470 {
7471 441779442 auto ffc_handle = *base_scr->getFFCHandle(q, screen_index_offset);
7472 441779442 int cid = ffc_handle.data();
7473 // auto& mini_cmb = combo_cache.minis[cid];
7474 // if (mini_cmb.trigger_global_state)
7475 441779442 auto& cmb = combobuf[cid];
7476
2/2
✓ Branch 0 taken 441779442 times.
✓ Branch 1 taken 228788 times.
442008230 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
7477 {
7478 228788 auto& trig = cmb.triggers[idx];
7479
1/2
✓ Branch 0 taken 228788 times.
✗ Branch 1 not taken.
228788 if (states[trig.trig_gstate])
7480 do_trigger_combo(ffc_handle, idx, ctrigSWITCHSTATE);
7481
1/2
✓ Branch 0 taken 228788 times.
✗ Branch 1 not taken.
228788 if(ffc_handle.data() != cid) break;
7482 228788 }
7483 441779442 }
7484 14790666 }
7485 15204141 }
7486 53777 void toggle_gswitches_load(const screen_handles_t& screen_handles)
7487 {
7488 bool states[256];
7489
2/2
✓ Branch 0 taken 13766912 times.
✓ Branch 1 taken 53777 times.
13820689 for(auto q = 0; q < 256; ++q)
7490 {
7491 13766912 states[q] = game->gswitch_timers[q] != 0;
7492 13766912 }
7493 53777 toggle_gswitches(states, true, screen_handles);
7494 53777 }
7495 14760996 void run_gswitch_timers()
7496 {
7497 14760996 bool states[256] = {false};
7498 14760996 auto& m = game->gswitch_timers.mut_inner();
7499
2/2
✓ Branch 0 taken 3774772736 times.
✓ Branch 1 taken 14760996 times.
3789533732 for(auto it = m.begin(); it != m.end();)
7500 {
7501
1/2
✓ Branch 0 taken 3774772736 times.
✗ Branch 1 not taken.
3774772736 if(it->second > 0)
7502 if(!--it->second)
7503 {
7504 states[it->first] = true;
7505 it = m.erase(it);
7506 continue;
7507 }
7508 3774772736 ++it;
7509 }
7510 29911360 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7511 15150364 toggle_gswitches(states, false, create_screen_handles(scr));
7512 15150364 });
7513 14760996 }
7514 1109 void onload_gswitch_timers() //Reset all timers that were counting down, no trigger necessary
7515 {
7516
2/2
✓ Branch 0 taken 283904 times.
✓ Branch 1 taken 1109 times.
285013 for(auto q = 0; q < 256; ++q)
7517 {
7518
1/2
✓ Branch 0 taken 283904 times.
✗ Branch 1 not taken.
283904 if(game->gswitch_timers[q] > 0)
7519 game->gswitch_timers[q] = 0;
7520 283904 }
7521 1109 }
7522
7523 /**** View Map ****/
7524
7525 int32_t mapres = 0;
7526 int32_t view_map_show_mode = 3;
7527
7528 124544 bool displayOnMap(int32_t x, int32_t y)
7529 {
7530 124544 int32_t s = (y<<4) + x;
7531 124544 int mi = mapind(cur_map, s);
7532
2/2
✓ Branch 0 taken 67891 times.
✓ Branch 1 taken 56653 times.
124544 if (!(game->maps[mi]&mVISITED))
7533 67891 return false;
7534
7535 // Don't display if not part of DMap
7536
4/4
✓ Branch 0 taken 15628 times.
✓ Branch 1 taken 41025 times.
✓ Branch 2 taken 4655 times.
✓ Branch 3 taken 4311 times.
65619 if(((DMaps[cur_dmap].flags&dmfDMAPMAP) &&
7537
1/2
✓ Branch 0 taken 15628 times.
✗ Branch 1 not taken.
15628 (DMaps[cur_dmap].type != dmOVERW) &&
7538
2/2
✓ Branch 0 taken 12495 times.
✓ Branch 1 taken 3133 times.
15628 !(x >= DMaps[cur_dmap].xoff &&
7539
2/2
✓ Branch 0 taken 8966 times.
✓ Branch 1 taken 3529 times.
12495 x < DMaps[cur_dmap].xoff+8 &&
7540 8966 DMaps[cur_dmap].grid[y]&(128>>(x-DMaps[cur_dmap].xoff)))))
7541 10973 return false;
7542 else
7543 45680 return true;
7544 124544 }
7545
7546 973 void ViewMap()
7547 {
7548 973 ViewingMap = true;
7549
7550 973 BITMAP* mappic = NULL;
7551 static double scales[17] =
7552 {
7553 0.03125, 0.04419, 0.0625, 0.08839, 0.125, 0.177, 0.25, 0.3535,
7554 0.50, 0.707, 1.0, 1.414, 2.0, 2.828, 4.0, 5.657, 8.0
7555 };
7556
7557 973 int32_t px = ((8-(cur_screen&15)) << 9) - 256;
7558 973 int32_t py = ((4-(cur_screen>>4)) * 352) - 176;
7559 973 int32_t lx = ((cur_screen&15)<<8) + HeroX()+8;
7560 973 int32_t ly = ((cur_screen>>4)*176) + HeroY()+8;
7561 973 int32_t sc = 6;
7562
7563 973 bool done=false, redraw=true;
7564
7565 973 mappic = create_bitmap_ex(8,(256*16)>>mapres,(176*8)>>mapres);
7566
7567
1/2
✓ Branch 0 taken 973 times.
✗ Branch 1 not taken.
973 if(!mappic)
7568 {
7569 enter_sys_pal();
7570 jwin_alert("View Map","Not enough memory.",NULL,NULL,"OK",NULL,13,27,get_zc_font(font_lfont));
7571 exit_sys_pal();
7572 return;
7573 }
7574
7575 973 clear_to_color(mappic, WHITE);
7576
7577 973 auto prev_viewport = viewport;
7578 973 viewport.x = 0;
7579 973 viewport.y = 0;
7580
7581 // draw the map
7582 973 BITMAP* screen_bmp = create_bitmap_ex(8, 256, 176);
7583 973 combotile_add_x = 256;
7584 973 combotile_add_y = 0;
7585
2/2
✓ Branch 0 taken 7784 times.
✓ Branch 1 taken 973 times.
8757 for(int32_t y=0; y<8; y++)
7586 {
7587
2/2
✓ Branch 0 taken 124544 times.
✓ Branch 1 taken 7784 times.
132328 for(int32_t x=0; x<16; x++)
7588 {
7589
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 78864 times.
124544 if (!displayOnMap(x, y))
7590 78864 continue;
7591
7592 45680 int screen = map_scr_xy_to_index(x, y);
7593 45680 auto scrs = loadscr2(screen);
7594 45680 mapscr* scr = &scrs[0];
7595
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!scr->is_valid())
7596 continue;
7597
7598 screen_handles_t screen_handles;
7599
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i <= 6; i++)
7600
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103790 times.
✓ Branch 3 taken 215970 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
7601
7602 45680 int xx = 0;
7603 45680 int yy = -playing_field_offset;
7604
7605
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 45660 times.
45680 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7606 {
7607
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7608
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7609 20 }
7610
7611
2/2
✓ Branch 0 taken 175 times.
✓ Branch 1 taken 45505 times.
45680 if(XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
7612 {
7613
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7614
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_ffc_layer(screen_bmp, -3, screen_handles[0], xx, yy);
7615 175 }
7616
7617
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if(lenscheck(scr,0)) putscr(scr, screen_bmp, 0, 0);
7618
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 0, screen_handles[0], xx, yy);
7619
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[1], xx, yy);
7620
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 1, screen_handles[0], xx, yy);
7621
7622
2/2
✓ Branch 0 taken 45660 times.
✓ Branch 1 taken 20 times.
45680 if(!XOR((scr->flags7&fLAYER2BG), DMaps[cur_dmap].flags&dmfLAYER2BG))
7623 {
7624
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7625
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_ffc_layer(screen_bmp, 2, screen_handles[0], xx, yy);
7626 45660 }
7627
7628
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 putscrdoors(scr, screen_bmp, xx, yy);
7629
2/2
✓ Branch 0 taken 41678 times.
✓ Branch 1 taken 4002 times.
45680 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
7630 {
7631
1/2
✓ Branch 0 taken 41678 times.
✗ Branch 1 not taken.
41678 do_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7632
2/2
✓ Branch 0 taken 1782 times.
✓ Branch 1 taken 39896 times.
41678 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
7633 {
7634
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[1], xx, yy);
7635
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[2], xx, yy);
7636 1782 }
7637 41678 }
7638
7639
2/2
✓ Branch 0 taken 45505 times.
✓ Branch 1 taken 175 times.
45680 if(!XOR((scr->flags7&fLAYER3BG), DMaps[cur_dmap].flags&dmfLAYER3BG))
7640 {
7641
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7642
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_ffc_layer(screen_bmp, 3, screen_handles[0], xx, yy);
7643 45505 }
7644
7645
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[4], xx, yy);
7646
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 4, screen_handles[0], xx, yy);
7647
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7648
2/2
✓ Branch 0 taken 5784 times.
✓ Branch 1 taken 39896 times.
45680 if(get_qr(qr_OVERHEAD_COMBOS_L1_L2))
7649 {
7650
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[1], xx, yy);
7651
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[2], xx, yy);
7652 5784 }
7653
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[5], xx, yy);
7654
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 5, screen_handles[0], xx, yy);
7655
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(replay_version_check(40))
7656 do_ffc_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7657
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[6], xx, yy);
7658
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 6, screen_handles[0], xx, yy);
7659
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 7, screen_handles[0], xx, yy);
7660
7661
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 stretch_blit(screen_bmp, mappic, 0, 0, 256, 176, x<<(8-mapres), (y*176)>>mapres, 256>>mapres, 176>>mapres);
7662
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
45680 }
7663 7784 }
7664
7665 973 viewport = prev_viewport;
7666 973 combotile_add_x = 0;
7667 973 combotile_add_y = 0;
7668
7669 973 destroy_bitmap(screen_bmp);
7670 973 clear_keybuf();
7671 973 pause_all_sfx();
7672
7673 // view it
7674 973 int32_t delay = 0;
7675
7676 973 do
7677 {
7678
2/2
✓ Branch 0 taken 178717 times.
✓ Branch 1 taken 29891 times.
208608 if (replay_version_check(0, 11))
7679 29891 load_control_state();
7680
7681 208608 int32_t step = int32_t(16.0/scales[sc]);
7682 208608 step = (step>>1) + (step&1);
7683 208608 bool r = cRbtn();
7684
7685
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(cLbtn())
7686 {
7687 step <<= 2;
7688 delay = 0;
7689 }
7690
7691
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 208608 times.
208608 if(r)
7692 {
7693 if(rUp())
7694 {
7695 py+=step;
7696 redraw=true;
7697 }
7698
7699 if(rDown())
7700 {
7701 py-=step;
7702 redraw=true;
7703 }
7704
7705 if(rLeft())
7706 {
7707 px+=step;
7708 redraw=true;
7709 }
7710
7711 if(rRight())
7712 {
7713 px-=step;
7714 redraw=true;
7715 }
7716 }
7717 else
7718 {
7719
2/2
✓ Branch 0 taken 193729 times.
✓ Branch 1 taken 14879 times.
208608 if(Up())
7720 {
7721 14879 py+=step;
7722 14879 redraw=true;
7723 14879 }
7724
7725
2/2
✓ Branch 0 taken 193574 times.
✓ Branch 1 taken 15034 times.
208608 if(Down())
7726 {
7727 15034 py-=step;
7728 15034 redraw=true;
7729 15034 }
7730
7731
2/2
✓ Branch 0 taken 182159 times.
✓ Branch 1 taken 26449 times.
208608 if(Left())
7732 {
7733 26449 px+=step;
7734 26449 redraw=true;
7735 26449 }
7736
7737
2/2
✓ Branch 0 taken 182774 times.
✓ Branch 1 taken 25834 times.
208608 if(Right())
7738 {
7739 25834 px-=step;
7740 25834 redraw=true;
7741 25834 }
7742 }
7743
7744
2/2
✓ Branch 0 taken 187444 times.
✓ Branch 1 taken 21164 times.
208608 if(delay)
7745 21164 --delay;
7746 else
7747 {
7748 187444 bool a = cAbtn();
7749 187444 bool b = cBbtn();
7750
7751
3/4
✓ Branch 0 taken 1721 times.
✓ Branch 1 taken 185723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1721 times.
187444 if(a && !b)
7752 {
7753
1/2
✓ Branch 0 taken 1721 times.
✗ Branch 1 not taken.
1721 sc=zc_min(sc+1,16);
7754 1721 delay=8;
7755 1721 redraw=true;
7756 1721 }
7757
7758
3/4
✓ Branch 0 taken 927 times.
✓ Branch 1 taken 186517 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 927 times.
187444 if(b && !a)
7759 {
7760
2/2
✓ Branch 0 taken 926 times.
✓ Branch 1 taken 1 times.
927 sc=zc_max(sc-1,0);
7761 927 delay=8;
7762 927 redraw=true;
7763 927 }
7764 }
7765
7766
2/2
✓ Branch 0 taken 208597 times.
✓ Branch 1 taken 11 times.
208608 if(rPbtn())
7767 11 --view_map_show_mode;
7768
7769 208608 px = vbound(px,-4096,4096);
7770 208608 py = vbound(py,-1408,1408);
7771
7772 208608 double scale = scales[sc];
7773
7774
2/2
✓ Branch 0 taken 72838 times.
✓ Branch 1 taken 135770 times.
208608 if(!redraw)
7775 {
7776 135770 blit(scrollbuf_old,framebuf,256,0,0,0,256,232);
7777 135770 }
7778 else
7779 {
7780 72838 clear_to_color(framebuf,BLACK);
7781 145676 stretch_blit(mappic,framebuf,0,0,mappic->w,mappic->h,
7782 72838 int32_t(256+(int64_t(px)-mappic->w)*scale)/2,int32_t(224+(int64_t(py)-mappic->h)*scale)/2,
7783 72838 int32_t(mappic->w*scale),int32_t(mappic->h*scale));
7784
7785 72838 blit(framebuf,scrollbuf_old,0,0,256,0,256,232);
7786 72838 redraw=false;
7787 }
7788
7789 208608 int32_t x = int32_t(256+(px-((2048-int64_t(lx))*2))*scale)/2;
7790 208608 int32_t y = int32_t(224+(py-((704-int64_t(ly))*2))*scale)/2;
7791
7792
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 201142 times.
208608 if(view_map_show_mode&1)
7793 {
7794 201142 line(framebuf,x-7,y-7,x+7,y+7,(frame&3)+252);
7795 201142 line(framebuf,x+7,y-7,x-7,y+7,(frame&3)+252);
7796 201142 }
7797
7798
3/4
✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 203008 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5600 times.
208608 if(view_map_show_mode&2 || r)
7799 203008 textprintf_ex(framebuf,font,224,216,WHITE,BLACK,"%1.2f",scale);
7800
7801
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(r)
7802 {
7803 textprintf_ex(framebuf,font,0,208,WHITE,BLACK,"m: %d %d",px,py);
7804 textprintf_ex(framebuf,font,0,216,WHITE,BLACK,"x: %d %d",x,y);
7805 }
7806
7807 208608 advanceframe(false, false);
7808
2/2
✓ Branch 0 taken 29891 times.
✓ Branch 1 taken 178717 times.
208608 if (replay_version_check(11))
7809 178717 load_control_state();
7810
7811
2/2
✓ Branch 0 taken 207636 times.
✓ Branch 1 taken 972 times.
208608 if(getInput(btnS, true, false, true)) //rSbtn
7812 972 done = true;
7813
7814
2/2
✓ Branch 0 taken 973 times.
✓ Branch 1 taken 207635 times.
417216 }
7815
2/2
✓ Branch 0 taken 972 times.
✓ Branch 1 taken 207636 times.
208608 while(!done && !Quit);
7816
7817 973 ViewingMap = false;
7818 973 destroy_bitmap(mappic);
7819 973 resume_all_sfx();
7820 973 }
7821
7822 1075 int32_t onViewMap()
7823 {
7824
4/6
✓ Branch 0 taken 1075 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1075 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 973 times.
1075 if(Playing && cur_screen<128 && DMaps[cur_dmap].flags&dmfVIEWMAP)
7825 {
7826 973 clear_to_color(framebuf,BLACK);
7827 973 textout_centre_ex(framebuf,font,"Drawing map...",128,108,WHITE,BLACK);
7828 973 advanceframe(true);
7829 973 ViewMap();
7830 973 }
7831
7832 1075 return D_O_K;
7833 }
7834
7835 35695413 bool isGrassType(int32_t type)
7836 {
7837
2/2
✓ Branch 0 taken 35019001 times.
✓ Branch 1 taken 676412 times.
35695413 switch(type)
7838 {
7839 case cTALLGRASS:
7840 case cTALLGRASSNEXT:
7841 case cTALLGRASSTOUCHY:
7842 676412 return true;
7843 }
7844
7845 35019001 return false;
7846 35695413 }
7847
7848 20914 bool isFlowersType(int32_t type)
7849 {
7850
2/2
✓ Branch 0 taken 16574 times.
✓ Branch 1 taken 4340 times.
20914 switch(type)
7851 {
7852 case cFLOWERS:
7853 case cFLOWERSTOUCHY:
7854 4340 return true;
7855 }
7856
7857 16574 return false;
7858 20914 }
7859
7860 bool isGenericType(int32_t type)
7861 {
7862 switch(type)
7863 {
7864 case cTRIGGERGENERIC:
7865 return true;
7866 }
7867
7868 return false;
7869 }
7870
7871 26056 bool isBushType(int32_t type)
7872 {
7873
2/2
✓ Branch 0 taken 20914 times.
✓ Branch 1 taken 5142 times.
26056 switch(type)
7874 {
7875 case cBUSH:
7876 case cBUSHNEXT:
7877 case cBUSHTOUCHY:
7878 case cBUSHNEXTTOUCHY:
7879
7880 5142 return true;
7881 }
7882
7883 20914 return false;
7884 26056 }
7885
7886 bool isSlashType(int32_t type)
7887 {
7888 switch(type)
7889 {
7890 case cSLASH:
7891 case cSLASHITEM:
7892 case cSLASHTOUCHY:
7893 case cSLASHITEMTOUCHY:
7894 case cSLASHNEXT:
7895 case cSLASHNEXTITEM:
7896 case cSLASHNEXTTOUCHY:
7897 case cSLASHNEXTITEMTOUCHY:
7898 return true;
7899 }
7900
7901 return false;
7902 }
7903
7904 15695 bool isCuttableNextType(int32_t type)
7905 {
7906
2/2
✓ Branch 0 taken 9788 times.
✓ Branch 1 taken 5907 times.
15695 switch(type)
7907 {
7908 case cSLASHNEXT:
7909 case cSLASHNEXTITEM:
7910 case cTALLGRASSNEXT:
7911 case cBUSHNEXT:
7912 case cSLASHNEXTTOUCHY:
7913 case cSLASHNEXTITEMTOUCHY:
7914 case cBUSHNEXTTOUCHY:
7915 5907 return true;
7916 }
7917
7918 9788 return false;
7919 15695 }
7920
7921 17546 bool isTouchyType(int32_t type)
7922 {
7923
2/2
✓ Branch 0 taken 6050 times.
✓ Branch 1 taken 11496 times.
17546 switch(type)
7924 {
7925 case cSLASHTOUCHY:
7926 case cSLASHITEMTOUCHY:
7927 case cBUSHTOUCHY:
7928 case cFLOWERSTOUCHY:
7929 case cTALLGRASSTOUCHY:
7930 case cSLASHNEXTTOUCHY:
7931 case cSLASHNEXTITEMTOUCHY:
7932 case cBUSHNEXTTOUCHY:
7933 11496 return true;
7934 }
7935
7936 6050 return false;
7937 17546 }
7938
7939 29325925 bool isCuttableType(int32_t type)
7940 {
7941
2/2
✓ Branch 0 taken 28876660 times.
✓ Branch 1 taken 449265 times.
29325925 switch(type)
7942 {
7943 case cSLASH:
7944 case cSLASHITEM:
7945 case cBUSH:
7946 case cFLOWERS:
7947 case cTALLGRASS:
7948 case cTALLGRASSNEXT:
7949 case cSLASHNEXT:
7950 case cSLASHNEXTITEM:
7951 case cBUSHNEXT:
7952
7953 case cSLASHTOUCHY:
7954 case cSLASHITEMTOUCHY:
7955 case cBUSHTOUCHY:
7956 case cFLOWERSTOUCHY:
7957 case cTALLGRASSTOUCHY:
7958 case cSLASHNEXTTOUCHY:
7959 case cSLASHNEXTITEMTOUCHY:
7960 case cBUSHNEXTTOUCHY:
7961 449265 return true;
7962 }
7963
7964 28876660 return false;
7965 29325925 }
7966
7967 17322 bool isCuttableItemType(int32_t type)
7968 {
7969
2/2
✓ Branch 0 taken 424 times.
✓ Branch 1 taken 16898 times.
17322 switch(type)
7970 {
7971 case cSLASHITEM:
7972 case cBUSH:
7973 case cFLOWERS:
7974 case cTALLGRASS:
7975 case cTALLGRASSNEXT:
7976 case cSLASHNEXTITEM:
7977 case cBUSHNEXT:
7978
7979 case cSLASHITEMTOUCHY:
7980 case cBUSHTOUCHY:
7981 case cFLOWERSTOUCHY:
7982 case cTALLGRASSTOUCHY:
7983 case cSLASHNEXTITEMTOUCHY:
7984 case cBUSHNEXTTOUCHY:
7985 16898 return true;
7986 }
7987
7988 424 return false;
7989 17322 }
7990
7991 66 bool is_push(mapscr* m, int32_t pos)
7992 {
7993
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(m->sflag[pos]))
7994 return true;
7995 66 newcombo const& cmb = combobuf[m->data[pos]];
7996
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(cmb.flag))
7997 return true;
7998
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 52 times.
66 if(cmb.type == cPUSHBLOCK)
7999 14 return true;
8000
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
52 if(cmb.type == cSWITCHHOOK && (cmb.usrflags&cflag7))
8001 return true; //Counts as 'pushblock' flag
8002 52 return false;
8003 66 }
8004
8005 404 static std::map<int, screen_state_t> screen_states;
8006
8007 35830 std::map<int, screen_state_t>& get_screen_states()
8008 {
8009 35830 return screen_states;
8010 }
8011
8012 44147606 screen_state_t& get_screen_state(int screen)
8013 {
8014 44147606 return screen_states[screen];
8015 }
8016
8017 568 void clear_screen_states()
8018 {
8019 568 screen_states.clear();
8020 568 }
8021
8022 1438 void screen_item_set_state(int screen, ScreenItemState state)
8023 {
8024 1438 get_screen_state(screen).item_state = state;
8025 1438 }
8026
8027 36982 void mark_visited(int screen)
8028 {
8029
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 36507 times.
36982 if (screen < 0x80)
8030 {
8031
2/2
✓ Branch 0 taken 24597 times.
✓ Branch 1 taken 11910 times.
36507 if(DMaps[cur_dmap].flags&dmfVIEWMAP)
8032 11910 game->maps[mapind(cur_map, screen)] |= mVISITED;
8033
8034 36507 markBmap(-1, screen);
8035 36507 }
8036 36982 }
8037